リポジトリパターンを適切に使用する方法を理解しようとしています。アグリゲートルートの中心的な概念が次々と登場します。WebとStack Overflowの両方で集約ルートのヘルプを検索すると、それらについての議論と、ベース定義が含まれているはずのページへのデッドリンクが見つかります。
リポジトリパターンのコンテキストでは、集約ルートとは何ですか?
リポジトリパターンを適切に使用する方法を理解しようとしています。アグリゲートルートの中心的な概念が次々と登場します。WebとStack Overflowの両方で集約ルートのヘルプを検索すると、それらについての議論と、ベース定義が含まれているはずのページへのデッドリンクが見つかります。
リポジトリパターンのコンテキストでは、集約ルートとは何ですか?
回答:
リポジトリパターンのコンテキストでは、集約ルートは、クライアントコードがリポジトリからロードする唯一のオブジェクトです。
リポジトリは子オブジェクトへのアクセスをカプセル化します-呼び出し元の観点から、ルートのロードと同時に、またはそれらが実際に必要なときに(遅延ロードの場合と同様に)自動的にロードします。
たとえば、Order
複数のLineItem
オブジェクトの操作をカプセル化するオブジェクトがあるとします。クライアントコードは、LineItem
オブジェクトを直接ロードすることはなく、オブジェクトOrder
を含むオブジェクトのみをロードします。これは、ドメインのその部分の集約ルートになります。
エバンスDDDから:
AGGREGATEは、データ変更の目的で1つの単位として扱う関連オブジェクトのクラスターです。各AGGREGATEには、ルートと境界があります。境界は、AGGREGATEの内部を定義します。ルートは、AGGREGATEに含まれる単一の特定のENTITYです。
そして:
ルートはAGGREGATEの唯一のメンバーであり、外部オブジェクトは[。]への参照を保持できます。
つまり、集約ルートは、リポジトリからロードできる唯一のオブジェクトです。
例は、Customer
エンティティとエンティティを含むモデルAddress
です。Address
関連するのコンテキストがないと意味がないため、モデルからエンティティに直接アクセスすることはありませんCustomer
。つまり、それが集合体を形成し、それが集合体ルートであるCustomer
と言えます。Address
Customer
Each AGGREGATE has a root
そしてThe root is the only *member* of the AGGREGATE
-この言い回しは、ルートが集合体のプロパティであることを意味します。しかし、すべての例で、それは逆です。ルートには、集約されたプロパティが含まれています。明確にできますか?
Customer
クラスは集約ルートまたはCustomer
インスタンスと見なされますか?
集約ルートは、単純なアイデアの複雑な名前です。
適切に設計されたクラス図は、その内部をカプセル化しています。この構造にアクセスするためのポイントはと呼ばれaggregate root
ます。
ソリューションの内部は非常に複雑な場合がありますが、この階層のユーザーは単にを使用しますroot.doSomethingWhichHasBusinessMeaning()
。
どのように車に乗りたいですか?より良いAPIを選択しました
オプションA(それは何とかうまくいく):
car.ride();
オプションB(ユーザーはクラスの内部にアクセスできます):
if(car.getTires().getUsageLevel()< Car.ACCEPTABLE_TIRE_USAGE)
for (Wheel w: car:getWheels()){
w.spin();
}
}
オプションAの方が良いとお考えの場合は、おめでとうございます。あなたは背後にある主な理由を取得しaggregate root
ます。
集約ルートは複数のクラスをカプセル化します。メインオブジェクトを介してのみ階層全体を操作できます。
car
集約ルートにアクセスできる必要があります。図面のような状況を許可することもできます。正しい解決策は、アプリケーションのビジネスモデルによって異なります。場合によって異なります。
コンピューターエンティティがあるとします。このエンティティも、ソフトウェアエンティティとハードウェアエンティティなしでは生きられません。これらComputer
は、ドメインのコンピュータ部分のミニエコシステムである集合体を形成します。
Aggregate Rootは、Aggregate内のマザーシップエンティティです(私たちの場合Computer
)。リポジトリがAggregate Rootであるエンティティでのみ機能することは一般的な慣例であり、このエンティティは他のエンティティの初期化を担当します。
Aggregate RootをAggregateへのエントリポイントとして検討します。
C#コード:
public class Computer : IEntity, IAggregateRoot
{
public Hardware Hardware { get; set; }
public Software Software { get; set; }
}
public class Hardware : IEntity { }
public class Software : IValueObject { }
public class Repository<T> : IRepository<T> where T : IAggregateRoot {}
ハードウェアもValueObjectである可能性が高いことに注意してください(それ自体にはIDがありません)。これは単なる例として考えてください。
where T : IAggregateRoot
-これは私の日を作った
データベースファーストのアプローチに従う場合、ルートは通常、1対多の関係の片側のテーブルです。
最も一般的な例は人物です。一人一人が多くの住所、1つ以上の支払い伝票、請求書、CRMエントリなどを持っています。常にそうであるとは限りませんが、9/10倍です。
現在、eコマースプラットフォームに取り組んでおり、基本的に2つのルートがあります。
顧客は連絡先情報を提供し、トランザクションを割り当て、トランザクションはラインアイテムを取得します。
売り手は製品を販売し、連絡先を持ち、私たちについてのページ、特別オファーなどを持っています。
これらは、それぞれCustomerリポジトリとSellerリポジトリによって処理されます。
ダイナ:
リポジトリーのコンテキストでは、集約ルートは親エンティティーのないエンティティーです。これには、その存在が親のアイデンティティーに依存しているゼロ、1つまたは多数の子エンティティが含まれます。これは、リポジトリにおける1対多の関係です。これらの子エンティティはプレーンアグリゲートです。
Aggregateは、不変条件を保護し、アクセスの集計ルートを制限することで一貫性を強制する場所です。集計はデータベースの関係ではなく、プロジェクトのビジネスルールと不変式に基づいて設計する必要があることを忘れないでください。リポジトリを挿入しないでください。クエリは許可されません。
Erlangでは、OO構成ではなく状態内のデータ構造によって集約が構成されると、集約を区別する必要はありません。例を参照してください:https : //github.com/bryanhunter/cqrs-with-erlang/tree/ndc-london