Php 我们是否应该以存储库模式保存/更新模型?

Php 我们是否应该以存储库模式保存/更新模型?,php,laravel,oop,design-patterns,repository-pattern,Php,Laravel,Oop,Design Patterns,Repository Pattern,我正在学习存储库模式,我已经看到了许多使用存储库模式进行创建和更新的示例。 下面是repisotory接口的一个示例 interface RepositoryInterface { public function all(); public function create(array $data); public function update(array $data, $id); public function delete($id); publ

我正在学习存储库模式,我已经看到了许多使用存储库模式进行创建和更新的示例。 下面是repisotory接口的一个示例

interface RepositoryInterface
{
    public function all();

    public function create(array $data);

    public function update(array $data, $id);

    public function delete($id);

    public function show($id);
}
此存储库接口负责创建/检索和更新模型

但是,在进行了更好的搜索之后,我发现人们应该避免将数据持久保存在存储库中,存储库应该充当集合,并且只用于检索数据。这是你的电话号码

这里是他们说的

存储库最重要的区别可能是它们代表实体的集合。它们不代表数据库存储或缓存或任何数量的技术问题。存储库表示集合。如何保存这些集合只是一个实现细节

下面是一个仅检索数据的存储库示例

interface BlogRepositoryInterface
{
    public function all();

    public function getByUser(User $user);
}
我想知道什么是存储库模式的最佳实践


如果我们只使用存储库来检索模型,那么我们如何处理创建/更新/删除模型?

我认为您误解了您引用的句子:

关于存储库最重要的区别可能是 它们代表实体的集合。它们不代表数据库 存储或缓存或任何数量的技术问题。存储库 表示集合。如何保存这些收藏只是一个简单的问题 实施细节

没有声明说您应该只使用存储库进行阅读。存储库最重要的特征是,当您使用存储库创建或更新项目时,更改可能不会立即应用于持久性层。应用更改的时间取决于存储库的实现


我的一个小提示是,我们不应该在存储库中有一个名为
create
的方法。作为一个集合,我们向其中添加项目,而不是创建项目。在我的存储库界面中,我通常有一个
add
方法,而不是
create
方法。创建应由工厂负责。

存储库模式完全允许对象持久性

来自Martin Fowler的书《企业应用程序架构模式》(第322页):

存储库在域和数据映射层之间进行中介,就像内存中的域对象集合一样。客户机对象以声明方式构造查询规范,并将其提交到存储库以满足需求。对象可以添加到存储库中,也可以从存储库中删除,就像它们可以从简单的对象集合中删除一样,存储库封装的映射代码将在幕后执行适当的操作

摘录很清楚:由于存储库是一个集合,您应该能够随意添加和删除其中的对象

我唯一关心的是你的界面。您应该将其拆分为两个或多个,因为您可能会有以下对象:

  • 不意味着要删除
  • 不打算更新
  • 不是要插入的
创建不同的接口将使您的代码符合接口隔离原则,即不应强制任何客户端依赖它不使用的方法

一些例子:

  • 假设您有一个代表您国家一个州的类。很少看到一个国家频繁地增加新的州,删除或更改其名称。因此,类
    State
    可以实现一个只包含方法
    all()
    show()
    的接口

  • 假设您正在编写一个电子商务。从数据库中删除
    客户
    不是一个选项,因为他所有的数据(如购买历史记录、搜索等)都将丢失。因此,您可以进行软删除,设置一个标志
    $customer->deleted=true。在这种情况下,类
    Customer
    可以实现一个只包含方法
    all()
    show()
    的接口,以及方法
    insert()
    update()
    的其他接口或两个接口


对此有很多答案,大多数都是个人意见。按你喜欢的方式去做。@Jonnix当然,但我想听听其他人的意见。您对存储库模式的实践是什么?您是将其用于crud还是仅用于检索?另外,如果您仅将其用于检索,那么您在哪里处理删除/删除/更新方法?征求人们的意见被认为是离题的。您的意思是创建两个单独的接口吗?一个用于检索,另一个用于创建/更新/删除?然后制作一个类来实现两个接口?是的,实际上是两个或更多的接口。我编辑了答案以提供一些例子