我正在编写一个ORM,不确定存储库的预期行为,或者更准确地说,存储库和工作单元之间的边界。据我了解,存储库可能如下所示:
interface IPersonRepository
{
public function find(Criteria criteria);
public function add(Person person);
public function delete(Person person);
}
根据福勒(PoEAA,第322页):
存储库在域和数据映射层之间进行调解,其作用类似于内存中的域对象集合。[...]可以将对象添加到存储库中或从存储库中删除对象,就像可以从简单的对象集合中删除对象一样。
这意味着以下测试应该有效(假设我们已经有一个人,他的姓氏是福勒):
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。
但是,这不是工作单元的作用,决定将哪个模型持久化到数据库中,以及何时持久化吗?
在上面的实现中,存储库必须决定在收到另一个 find() 调用时保留之前检索到的人,以便结果与修改一致。但是,如果没有发出其他 find() 调用,则模型根本不会被隐式持久化。
在工作单元的上下文中,这不是真正的问题,因为我们可以在开始时启动事务,并在需要时回滚任何插入到数据库。但是,当单独使用时,此存储库不会导致意外的、不可预测的行为吗?
存储库在 域和数据映射层,作用 类似于内存中的域对象 收集。[...]可以添加对象 到存储库并从存储库中删除,作为 他们可以从一个简单的集合 对象。
这并不意味着您不需要保存方法。您仍需要将更改显式提交到存储。
查看工作单元模式和持久性无知
public interface IUnitOfWork {
void MarkDirty(object entity);
void MarkNew(object entity);
void MarkDeleted(object entity);
void Commit();
void Rollback();
}
在某种程度上,您可以将工作单元视为转储所有事务处理代码的地方。工作单元的职责是:
- 管理交易。
- 对数据库插入、删除和更新进行排序。
- 防止重复更新。在工作单元对象的单个用法中,代码的不同部分可能会将同一发票对象标记为已更改,但工作单元类只会向 databa 发出单个 UPDATE 命令。
我认为您要问的是以下内容:http://martinfowler.com/eaaCatalog/identityMap.html
存储库应将获取的对象保留在内存中,并且不应从持久性存储中检索对该实体的所有后续调用,因此您的示例应该可以正常工作。