5

私は、集合体の一部であるエンティティの変化を検出するために、人々がどのようなアプローチをとったかを調べています。私はうまくいくものを持っていますが、私はそれに夢中ではありません。基本的に、私のリポジトリは、集約ルートの状態が変化したかどうかを判断する責任があります。集約ルートが呼び出され、集約内でBookエンティティが呼び出されたとPageします。には、コレクションに格納されたBook1 つ以上のPageエンティティが含まれます。Pages

主に、挿入と更新のシナリオは、集約ルートとそのエンティティを調べてキーの存在を判断することによって行われます。キーが存在する場合、オブジェクトは一度に基になるデータ ソースに保存されていると見なされます。これにより、更新の候補になります。しかし、それはエンティティのそれだけに基づいて決定的なものではありません. 集約ルートを使用すると、答えは明らかです。1 つしかなく、それが特異なエントリ ポイントであるため、キーの存在によって操作が決まると想定できます。私の場合、変更日を取得できるように、集約ルート自体を再度保存することは許容されるシナリオです。

エンティティ自体のこの動作を容易にするために、私のEntityBaseクラスには , の 2 つの単純なプロパティが含まれていIsUpdated()ますIsDeleted()。これらのデフォルトは両方とも false です。前述のように、キーの存在に基づいて判断できるため、新しいかどうかを知る必要はありません。実装のメソッド (この場合はページ) には、バッキング データ セットIsUpdated()を true に変更する各メソッドがあります。

したがって、たとえば、ページには、読み取り専用のプロパティUpdateSectionName()のバッキング値を変更するメソッドが呼び出されます。SectionNameこのアプローチは一貫して使用されます。これは、そのデータ設定を実行するメソッドでバリデーターの論理接続ポイントを許可するためです (エンティティが無効な状態に入るのを防ぎます)。最終結果はthis.IsUpdated() = true;、メソッドの最後に a を配置する必要があるということです。

集約ルートが のリポジトリに送信されると(または操作Save()へのロジック スイッチ)、 のコレクションを反復処理して、次の 3 つのシナリオのいずれかを持つページを探します。Insert()Update()PagesBook

  1. 鍵がありません。キーのないAPageが挿入されます。
  2. IsDeleted = true;削除は更新よりも優先され、削除はコミットされます - の更新は無視されますPage
  3. IsUpdated = true;ページの更新がコミットされます。

このようにすることで、Pages コレクション内のすべてをやみくもに更新することを防ぐことができます。たとえば、Book に数百の Page エンティティがある場合、これは困難な作業になる可能性があります。私は本のコピーを取得し、比較を行い、検出された変更 (存在および/または比較に基づいて挿入、更新、および削除) のみをコミットすることを検討していましたが、それは非常におしゃべりな方法のようでした。 .

主な欠点は、開発者がエンティティ内の各メソッドで IsUpdated を設定することを覚えておく必要があることです。1 つ忘れると、その値の変更を検出できなくなります。私は、透過的に変更にタイムスタンプを付けることができるある種のカスタム バッキング ストアのアイデアをいじりました。これによりIsUpdated、リポジトリが更新を集約するために使用できる読み取り専用プロパティを作成できます。

リポジトリは、集約ルートが追加されたときに生成されたタイムスタンプに基づいてアクションを実行する作業単位パターンの実装を使用しています。操作のために複数のエンティティがキューに入れられている可能性があるため、エンティティ操作はロールアップされ、エンティティが属する集約ルート操作が実行された直後に実行されます。さらに一歩進んで、エンティティ操作を処理する別の作業単位を作成し、エンティティで使用されるある種のイベント追跡に基づいていることがわかります (これは、市場に出回っている ORM 製品のいくつかが達成すると想定している方法です)。同様のレベルの機能)。

ただし、この方向に進み続ける前に、これに関するアイデア/推奨事項/経験を聞きたいです.

編集:知っておくと役立ついくつかの追加情報:

  1. 私が現在取り組んでいる言語は C# ですが、これは理論的な議論に近いため、言語固有の情報をできるだけ多く出さないようにしました。
  2. リポジトリ/サービス/エンティティなどのコード。は、Tim McCarthy の著書「.NET Domain-Driven Design with C#」の概念とCodePlexのサポート コードに基づいています。私が取り組んでいるものはほとんど一から書き直されていますが、それは採用されたアプローチのタイプの実行可能な理解を提供します.
4

1 に答える 1

1

要するに、私の答えは、私が提案したことを行ったということです。改善の余地があると確信していますが、機能しています。実際、変更にはほとんど時間がかからなかったので、この場合、KISS や YAGNI の原則からあまり離れていなかったと思います。:-)

操作のタイミング関連の問題についてはまだ余地があると感じていますが、リポジトリの実装でそれらを回避できるはずです。理想的な解決策ではありませんが、修正にかかる時間よりも短い時間で回避できる問題を修正するために車輪を再発明する価値があるかどうかはわかりません.

于 2009-09-16T20:19:36.603 に答える