据我所知,存储库模式抽象了域对象的持久性,允许开发人员从持久存储中读取/写入/删除对象,而不知道对象的存储方式(SQL,NoSQL,平面文件等)。我非常喜欢存储库模式,并且发现它在许多情况下运行良好,例如,从持久性逻辑中抽象出业务逻辑,允许在适当的情况下延迟加载对象等。
但是,我不清楚的是存储库对象是否维护对所有对象的引用?例如:
Repository repository;
std::shared_ptr<Person> pPerson = repository.retrievePersonById("bob");
p->updateDetails("Bob", "the Builder");
repository.savePerson(p);
repository
是否应该维护对返回的Person
实例的引用? 是的 - 感谢Guillaume31进行内存类比。repository
应该何时以及如何删除Person
的该实例?大概这是指参考计数达到零时。repository
不再存储对它的内部引用时,你如何处理这种情况,它从数据库中保留了一个新的副本,当你真的应该引用同一个实例时,你实际上有两个Person
实例? 鉴于Q1的答案是&#34;是&#34;,然后存储库始终保持引用,因此应始终返回相同的对象。我实际上是在写一个PHP应用程序,尽管上面的例子是用C ++编写的。
答案 0 :(得分:1)
存储库的一个更恰当的比喻可能是它是内存中对象集合的错觉。从任何OO语言中获取基本集合类型。如果您从该集合中获取元素并修改该元素,则通常不必将其保存回集合中,因为它从未停止在集合中。
对于存储库也是如此 - 它为对象提供服务,可以向自身添加对象,但不会公开保存对底层存储的修改的任何功能。实际上,它完全是为了隐藏底层存储的存在。它没有公开任何方法来更新&#34;一个实体的状态,因为它所服务的实体在内存中,你可以自由地修改它,它永远不会同步。
如果存储库保持脱离事务管理和提交工作单元,那么它也会更好。您应该将其委托给客户端(参见Domain Driven Design第156页)。要回答您的问题,在业务事务中,您不应该假设存储库返回的对象的新鲜度。它们只是在某个时间点反映某些实体的状态,您所要做的就是按原样使用它们并使用它们。在更全球化的层面上,一些外部机制(通常是ORM工具)将使您能够管理如何将小企业事务与其他事务隔离开来,通常采用工作单元实现的形式。刷新对数据库的更改并处理潜在的陈旧实体问题不是每个存储库查询决策,它是一个更全局的业务事务级别决策,只有在您确定用例已完成并且您想要提交它时才会发生。