php - 在领域驱动设计中,存储库模式是否维护对对象的引用?

标签 php c++ domain-driven-design repository-pattern object-persistence

我理解存储库模式抽象了域对象的持久性,允许开发人员在不知道对象如何存储(SQL、NoSQL、平面文件等)的情况下从持久存储中读取/写入/删除对象。我非常喜欢存储库模式,并发现它在许多情况下都能很好地工作,例如,从持久化逻辑中抽象出业务逻辑,允许在适当的地方延迟加载对象等。

但是,我不清楚的是存储库对象是否维护对所有对象的引用?例如:

Repository repository;
std::shared_ptr<Person> pPerson = repository.retrievePersonById("bob");

p->updateDetails("Bob", "the Builder");
repository.savePerson(p);
  1. 在上面假设的 C++ 示例中,repository 是否应该维护对返回的 Person 实例的引用? 是的 - 感谢 Guillaume31 的内存类比
  2. 如果问题 1 的答案是"is",repository 应何时以及如何删除 Person 的实例?大概这是引用计数达到零的时候。
  3. 如果问题 1 的答案是“否”,当另一个区域想要访问同一对象,但由于 repository 不再存储对它的内部引用时,您如何处理这种情况来自数据库的新拷贝,而当您真的应该引用同一个实例时,您实际上有两个 Person 实例? 鉴于 Q1 的答案是"is",那么存储库始终维护一个引用,因此应该始终返回相同的对象

尽管上面的示例是用 C++ 编写的,但我实际上是在编写一个 PHP 应用程序。

最佳答案

对于存储库,一个更恰当的比喻可能是它是内存中对象集合的错觉。从任何 OO 语言中获取基本集合类型。如果您从该集合中获取一个元素并修改该元素,您之后通常不必将其保存回集合中,因为它从未停止在集合中。

存储库也是如此——它提供对象,可以向自身添加对象,但不公开任何用于保存对底层存储的修改的功能。事实上,这一切都是为了隐藏底层存储的存在。它也不会公开任何方法来“更新”实体的状态,因为它所服务的实体在内存中并且您可以自由修改它,它永远不会不同步。

如果存储库不干预事务管理和提交工作单元,也会更好。您应该将其委托(delegate)给客户端(请参阅领域驱动设计第 156 页)。

要回答您的问题,在业务事务中,您不应该对存储库返回的对象的新鲜度做出任何假设。它们只是反射(reflect)了某些实体在某个时间点的状态,你所要做的就是照原样使用它们。在更全局的层面上,一些外部机制(通常是 ORM 工具)将使您能够管理如何将您的小业务事务与其他事务隔离开来,通常以工作单元实现的形式。刷新对数据库的更改和处理潜在的陈旧实体问题不是每个存储库查询决策,它是一个更全局的业务事务级决策,只有当您决定用例已完成并想要提交时才应该发生。

关于php - 在领域驱动设计中,存储库模式是否维护对对象的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27978033/

相关文章:

domain-driven-design - 您能否建议DDD最佳做法

domain-driven-design - 领域服务控制粒度

node.js - "Failed to get configuration"通过 Node 在 Mocha 测试中使用 Wolkenkit 客户端

php - 悬停时内联样式背景更改

php - Mysql codeigniter php asc desc 使用 php 按计数结果排序

c++ - Boost库中用于动态位集的硬件支持的popcount

c++ - 我在哪里/如何获得 Looper?

php - Mysql 注释标签破坏了我的代码 (PHP)

php - 博客只显示一篇文章,为什么即使所有内容都已发布,

c++ - 强制 GPGME 中的 GPG 使用 CAST5 以外的密码