0

我正在编写一个 ORM,但不确定存储库的预期行为,或者更准确地说,不确定存储库和工作单元之间的边界。据我了解,存储库可能如下所示:

interface IPersonRepository
{
    public function find(Criteria criteria);
    public function add(Person person);
    public function delete(Person person);
}

根据福勒(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 模型也必须由 Repository 自动持久化,以便下一个查询返回正确的集合,而不包含原始 Person。

但是,这不是工作单元的角色,决定将哪个模型持久化到数据库,以及何时持久化?

在上述实现中,Repository 必须决定在接收到另一个 find() 调用时将之前检索到的 Person 持久化,以便结果与修改一致。但是,如果没有发出其他 find() 调用,则模型根本不会被隐式持久化。

在工作单元的上下文中,这不是一个真正的问题,因为我们可以在开始时启动一个事务,并在需要时将任何插入回滚到数据库。但是当单独使用时,这个 Repository 不会导致意想不到的、不可预测的行为吗?

4

2 回答 2

1

存储库在域和数据映射层之间进行调解,就像内存中的域对象集合一样。[...] 可以将对象添加到存储库中或从存储库中删除,就像它们可以从简单的对象集合中一样。

这并不意味着您不需要保存方法。您仍然需要明确提交对存储的更改。

查看工作单元模式和持久性无知

public interface IUnitOfWork {
  void MarkDirty(object entity);
  void MarkNew(object entity);
  void MarkDeleted(object entity);
  void Commit();
  void Rollback();
}

在某种程度上,您可以将工作单元视为转储所有事务处理代码的地方。工作单位的职责是:

  • 管理交易。
  • 对数据库的插入、删除和更新进行排序。
  • 防止重复更新。在 Unit of Work 对象的单一用法中,代码的不同部分可能会将同一个 Invoice 对象标记为已更改,但 Unit of Work 类只会向数据库发出单个 UPDATE 命令
于 2011-05-18T23:35:01.040 回答
0

我想你问的是:http ://martinfowler.com/eaaCatalog/identityMap.html

存储库应将获取的对象保留在内存中,并且不应从持久性存储中检索对该实体的所有后续调用,因此您的示例应该可以正常工作。

于 2011-06-09T02:15:53.543 回答