Laravel 存储库模式

Laravel Repository pattern

看了一些关于repository pattern的文章,想知道在直接调用模型和return数据的情况下为什么需要构造函数?我还认为 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();
    }
}

class BookRepository implements RepositoryInterface {

    public function index()
    {
        return Book::all();
    }
}

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

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

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

然而,这导致了不直接使用 classes 而是使用接口来声明依赖项的想法。这样任何实现都可以被换出并且您的代码保持可读性。

class BookRepository {

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

}

现在您的存储库并不真正关心实际的 class,只是它实现了强制定义一组特定方法的书籍接口。好处的一个例子是,如果您使用 MySQL 作为您的 Book 的数据库,但切换到 Postgres,您可能需要显着更改底层代码,但出于遗留原因希望保留这两个实现。您可以轻松地告诉 Laravel 加载您的标准 Book class 或您的新 PostgresBook class,因为两者仍然实现 BookInterface

您的存储库根本不需要更改。只需添加一个绑定就可以了。

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