php – 如果我在Laravel 5项目中使用andersao / l5-repository,我会打破控制原理的反转吗?

我是Laravel开发人员的新手,我正在尝试理解并应用SOLID原则,就像一个优秀的程序员.所以我最近在laravel中学习并应用了存储库模式.

为此,我创建了一个目录存档并使用psr-4加载它,如下所示:

"Archive\\": "archive/"

然后我创建了一个名为Repositories的文件夹,另一个名为Contracts的文件夹.现在在Contracts文件夹中我有UserRepositoryInterface和ServicesRepositoryInterface等接口,在Repositories文件夹外面,我有像DbUserRepository和DbServiceRepository等实现.

我正在使用一个名为DataServiceProvider的服务提供程序,我在其中绑定这些:

$this->app->bind(UserRepositoryInterface::class, DbUserRepository::class);
$this->app->bind(ServiceRepositoryInterface::class, DbServiceRepository::class);

因此,我可以在我的控制器中注入像UserRepositoryInterface和ServiceRepositoryInterface这样的联系人,Laravel会自动将我的依赖项从IoC容器中解析出来.因此,如果将来我需要一个FileUserRepository,我只需要创建该类并更改我的服务提供程序中的绑定,并且我的控制器中不会有任何中断.

这是我从泰勒和杰弗里那里学到的.但现在我正在尝试使用包https://github.com/andersao/l5-repository来实现我的项目.

根据这个,我将使用它附带的BaseRepository扩展我的DbUserRepository,如下所示:

namespace App;

use Prettus\Repository\Eloquent\BaseRepository;

class UserRepository extends BaseRepository {

    /**
     * Specify Model class name
     *
     * @return string
     */
    function model()
    {
        return "App\\Post";
    }
}

现在在这里,我显然重用BaseRepository附带的所有代码和功能,如all(),panginate($limit = null,$columns = [‘*’]),find($id)等,但现在我我打破了控制反转原理,因为现在我必须将具体的实现注入我的控制器中?

我仍然是一个新手开发人员并试图理解这一切,并在解释事情时可能在问题的某个地方出错.使用包装的最佳方法是什么,同时在控制器中保持松耦合?

最佳答案 你没有理由不能实现你的界面:

namespace App;

use Prettus\Repository\Eloquent\BaseRepository;

class DbUserRepository extends BaseRepository implements UserRepositoryInterface {

    /**
     * Specify Model class name
     *
     * @return string
     */
    function model()
    {
        return "App\\Post";
    }
}

但是,你现在面临一个问题;如果你换掉你的实现,你的UserRepositoryInterface中没有任何东西可以说也必须实现BaseRepository方法.如果你看一下BaseRepository类,你应该看到它实现了它自己的两个接口:RepositoryInterface和RepositoryCriteriaInterface和’幸运’php允许多个接口继承,这意味着你可以扩展你的UserRepositoryInterface,如下所示:

interface UserRepositoryInterface extends RepositoryInterface, RepositoryCriteriaInterface {

  // Declare UserRepositoryInterface methods

}

然后您可以正常绑定和使用您的界面:

$this-> app-> bind(UserRepositoryInterface :: class,DbUserRepository :: class);

点赞