0

私は ORM を書いていますが、リポジトリの予想される動作、またはより正確には、リポジトリと作業単位の間のフロンティアが不明です。私の理解では、リポジトリは次のようになります。

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

Fowler によると ( PoEAA、322 ページ):

リポジトリは、ドメイン レイヤーとデータ マッピング レイヤーの間を仲介し、メモリ内のドメイン オブジェクト コレクションのように機能します。[...] オブジェクトは、オブジェクトの単純なコレクションと同様に、リポジトリに追加および削除できます。

これは、次のテストが機能することを意味します (姓が Fowler である Person が永続化されていると仮定します)。

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 モデルがリポジトリによって自動的に永続化されている必要があります。

しかし、どのモデルをいつデータベースに永続化するかを決定するのは、Unit Of Work の役割ではないでしょうか。

上記の実装では、結果が変更と一致するように、リポジトリは別の find() 呼び出しを受け取ったときに以前に取得した Person を永続化することを決定する必要があります。しかし、他の find() 呼び出しが発行されなかった場合、モデルは暗黙的に永続化されませんでした。

Unit Of Work のコンテキストでは、最初にトランザクションを開始し、必要に応じてデータベースへの挿入をロールバックできるため、実際には問題になりません。しかし、このリポジトリを単独で使用すると、予期しない、予測不可能な動作につながることはありませんか?

4

2 に答える 2

1

リポジトリは、ドメイン レイヤーとデータ マッピング レイヤーの間を仲介し、メモリ内のドメイン オブジェクト コレクションのように機能します。[...] オブジェクトの単純なコレクションと同様に、オブジェクトをリポジトリに追加したり、リポジトリから削除したりできます。

これは、save メソッドが必要ないという意味ではありません。変更を明示的にストレージにコミットする必要があります。

作業単位パターンと永続性無視を参照してください

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

ある意味では、Unit of Work は、すべてのトランザクション処理コードをダンプする場所と考えることができます。作業単位の責任は次のとおりです。

  • トランザクションを管理します。
  • データベースの挿入、削除、および更新を順序付けます。
  • 重複更新を防ぎます。Unit of Work オブジェクトの 1 回の使用の内部では、コードのさまざまな部分が同じ Invoice オブジェクトを変更済みとしてマークする場合がありますが、Unit of Work クラスは単一の UPDATE コマンドをデータベースに発行するだけです。
于 2011-05-18T23:35:01.040 に答える
0

私はあなたが何を求めていると思います: http://martinfowler.com/eaaCatalog/identityMap.html

リポジトリはフェッチされたオブジェクトをメモリに保持する必要があり、そのエンティティに対する後続のすべての呼び出しは永続ストレージから取得されるべきではないため、例は正常に機能するはずです。

于 2011-06-09T02:15:53.543 に答える