Php Laravel存储库模式

Php Laravel存储库模式,php,laravel,repository-pattern,Php,Laravel,Repository Pattern,我读了一些关于存储库模式的文章,我想知道当我可以直接调用模型并返回数据时为什么需要构造函数?我还认为Book::all()的代码少于$this->model->all()。这只是一个好的做法还是有目的 class BookRepository implements RepositoryInterface { private $model; public function __construct(Book $model) { $this->mode

我读了一些关于存储库模式的文章,我想知道当我可以直接调用模型并返回数据时为什么需要构造函数?我还认为
Book::all()的代码少于
$this->model->all()
。这只是一个好的做法还是有目的

class BookRepository implements RepositoryInterface {

    private $model;

    public function __construct(Book $model)
    {
        $this->model = $model;
    }

    public function index()
    {
        return $this->model->all();
    }
}


两者都可以工作,但如果出于任何原因,您想用任何其他模型(例如[MyBook])更改模型类[Book],那么在这种情况下,您将只更改构造函数参数,而不是所有使用[Book]的函数

public function __construct(MyBook $model)
{
    $this->model = $model;
}

主要原因是控制反转,基本上是让您的应用程序决定应该提供什么来实现该依赖性。这一点很重要的原因是,如果您决定重构代码,您可以简单地告诉Laravel加载不同的实现。不需要在存储库中修改代码

然而,这导致了不直接使用类,而是使用接口来声明依赖性的想法。这样,任何实现都可以被替换掉,代码仍然可读

class BookRepository {

    public function __construct(BookInterface $book)
    {
        $this->book = $book;
    }

}
现在,您的存储库并不真正关心实际的类,只是它实现了book接口,该接口强制定义一组特定的方法。例如,如果您使用MySQL作为书籍的数据库,但改用Postgres,则可能需要显著更改底层代码,但出于遗留原因,希望保留这两种实现。您可以很容易地告诉Laravel加载您的标准
书籍
类或新的
PostgresBook
类,因为两者仍然实现
书籍界面

您的存储库根本不需要更改。只要加上一个绑定,你就很好了

另一个更直接的例子是,如果您决定从雄辩切换到ActiveRecord

class BookRepository {

    public function __construct(BookInterface $book)
    {
        $this->book = $book;
    }

}