存储库的预期行为
我正在编写一个 ORM,并且不确定存储库的预期行为,或者更准确地说,存储库和工作单元之间的边界。 根据我的理解,存储库可能如下所示:
interface IPersonRepository
{
public function find(Criteria criteria);
public function add(Person person);
public function delete(Person person);
}
根据 Fowler(PoEAA,第 322 页):
存储库在域和数据映射层之间进行中介,其作用类似于内存中的域对象集合。 [...] 可以在存储库中添加和删除对象,就像在简单的对象集合中一样。
这意味着以下测试应该有效(假设我们已经保存了一个 Person,其姓氏是 Fowler):
collection = repository.find(lastnameEqualsFowlerCriteria);
person = collection[0];
assertEquals(person.lastname, "Fowler");
person.lastname = "Evans";
newCollection = repository.find(lastnameEqualsFowlerCriteria);
assertFalse(newCollection.contains(person));
这意味着当映射到数据库时,即使某处没有调用显式 save() 方法,该 Person模型必须已由存储库自动保留,以便下一个查询返回正确的集合,不包含原始 Person。
但是,这不正是工作单元的作用吗?决定将哪个模型以及何时保存到数据库?
在上面的实现中,Repository 在收到另一个 find() 调用时必须决定保留先前检索到的 Person,以便结果与修改一致。但如果没有发出其他 find() 调用,则该模型根本不会隐式持久化。
在工作单元的上下文中,这并不是真正的问题,因为我们可以在开始时启动一个事务,并在需要时回滚任何对数据库的插入。 但是单独使用时,这个存储库不会导致意外的、不可预测的行为吗?
I'm writing an ORM and am unsure of the expected behaviour of the Repository, or more precisely, the frontier between the Repository and the Unit Of Work.
From my understanding, a Repository might look like this:
interface IPersonRepository
{
public function find(Criteria criteria);
public function add(Person person);
public function delete(Person person);
}
According to Fowler (PoEAA, page 322):
A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. [...] Objects can be added to and removed from the Repository, as they can from a simple collection of objects.
This would imply that the following test should work (assuming that we already have a Person persisted, whose last name is Fowler):
collection = repository.find(lastnameEqualsFowlerCriteria);
person = collection[0];
assertEquals(person.lastname, "Fowler");
person.lastname = "Evans";
newCollection = repository.find(lastnameEqualsFowlerCriteria);
assertFalse(newCollection.contains(person));
That means that when mapping to a database, even if no explicit save() method has been called somewhere, the Person model must have been automatically persisted by the Repository, so that the next query returned the correct collection, not containing the original Person.
But, isn't that the role of the Unit Of Work, to decide which model to persist to the database, and when?
In the above implementation, the Repository has to decide to persist the Person previously retrieved when receiving another find() call, so that the result is consistent with the modification. But if no other find() call were issued, the model would not have been persisted implicitly at all.
In the context of a Unit Of Work, it is not really a problem, because we can start a transaction at the beginning, and rollback any insert to the db anyway if needed.
But when used alone, can't this Repository lead to unexpected, unpredictable behaviour?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这并不意味着您不需要保存方法。您仍然需要显式地将更改提交到存储。
请参阅工作单元模式和持久性无知
在某种程度上,您可以将工作单元视为转储所有事务处理代码的地方。工作单元的职责是:
This does not mean you do not need a save method. You still need to explicitly commit your changes to storage.
See The Unit Of Work Pattern And Persistence Ignorance
In a way, you can think of the Unit of Work as a place to dump all transaction-handling code. The responsibilities of the Unit of Work are to:
我认为您要问的是以下内容: http://martinfowler.com/eaaCatalog/identityMap.html< /a>
存储库应将获取的对象保留在内存中,并且不应从持久性存储中检索对该实体的所有后续调用,因此您的示例应该可以正常工作。
I think what you;re asking about is following: http://martinfowler.com/eaaCatalog/identityMap.html
Repository should keep fetched objects in memory and all subsequent calls for that entity should not be retrieved from persistence storage, hence your example should work fine.