集計ルートとは何ですか?


447

リポジトリパターンを適切に使用する方法を理解しようとしています。アグリゲートルートの中心的な概念が次々と登場します。WebとStack Overflowの両方で集約ルートのヘルプを検索すると、それらについての議論と、ベース定義が含まれているはずのページへのデッドリンクが見つかります。

リポジトリパターンのコンテキストでは、集約ルートとは何ですか?


16
以下のケーススタディを検討することを検討してください。効果的な集計デザインパートI:単一の集計のモデリングdddcommunity.org/wp-content/uploads/files/pdf_articles/…パートII:集計を連携させるdddcommunity.org/wp-content/uploads/files/pdf_articles/…パートIII:ディスカバリーを通じて洞察を獲得dddcommunity.org/wp-content/uploads/files/pdf_articles/...
ベン・ヴィターレ

回答:


310

リポジトリパターンのコンテキストでは、集約ルートは、クライアントコードがリポジトリからロードする唯一のオブジェクトです。

リポジトリは子オブジェクトへのアクセスをカプセル化します-呼び出し元の観点から、ルートのロードと同時に、またはそれらが実際に必要なときに(遅延ロードの場合と同様に)自動的にロードします。

たとえば、Order複数のLineItemオブジェクトの操作をカプセル化するオブジェクトがあるとします。クライアントコードは、LineItemオブジェクトを直接ロードすることはなく、オブジェクトOrderを含むオブジェクトのみをロードします。これは、ドメインのその部分の集約ルートになります。


21
仮に、クライアントコードが他の目的でLineItemを必要とする場合、それは別の集約を形成しますか(Orderオブジェクトに関連しない他のオブジェクトが関与していると仮定して)?
Ahmad

20
@Ahmad、他の集計はLineItemを読み取り専用データとして参照する場合がありますが、変更することはできません。他の集計がそれらを変更する可能性がある場合、注文の不変条件(およびラインアイテム)を保護できません。
Jeff Sternal

4
これを見てください。例:lostechies.com/blogs/jimmy_bogard/archive/2010/02/23/…。この例では、CustomerはOrderの不変条件ですよね?ただし、お客様は別の集約ルートになることもできますか?または、ここでいくつかの基本的な理解が欠けていますか?
2010年

3
@ジェフあなたは「彼らはそれらを変更することはできない」と言いました-それは強制可能ですか、それとも慣習の問題ですか?
Neil Barnwell

4
@Neil:データを表すための不変クラスを作成するなど、利用可能な言語メカニズムを使用して強制します。
ジェフスターナル

206

エバンスDDDから:

AGGREGATEは、データ変更の目的で1つの単位として扱う関連オブジェクトのクラスターです。各AGGREGATEには、ルートと境界があります。境界は、AGGREGATEの内部を定義します。ルートは、AGGREGATEに含まれる単一の特定のENTITYです。

そして:

ルートはAGGREGATEの唯一のメンバーであり、外部オブジェクトは[。]への参照を保持できます。

つまり、集約ルートは、リポジトリからロードできる唯一のオブジェクトです。

例は、Customerエンティティとエンティティを含むモデルAddressです。Address関連するのコンテキストがないと意味がないため、モデルからエンティティに直接アクセスすることはありませんCustomer。つまり、それが集合体を形成し、それが集合体ルートであるCustomerと言えます。AddressCustomer


57
Eric Evansからの更新:集約ルートはトランザクション/並行性の整合性境界であることを強調し、外部エンティティが他の集約の子エンティティへの参照を保持できないことを強調しないでください。
ブライアンロー

3
だから言い回しは私を永遠に混乱させます。Each AGGREGATE has a rootそしてThe root is the only *member* of the AGGREGATE-この言い回しは、ルートが集合体のプロパティであることを意味します。しかし、すべての例で、それは逆です。ルートには、集約されたプロパティが含まれています。明確にできますか?
Sinaesthetic 2015年

1
私の言語を正しくするために、Customerクラスは集約ルートまたはCustomer インスタンスと見なされますか?
Joe

1
一般的に、Customer-order-line-itemパラダイムでは、顧客は集約ルートになります。顧客のインスタンスは、その集約ルートのインスタンスになります。Customerと呼ばれる集約ルートについて話すときは、顧客のインスタンスを構成するCustomerの論理構造について話し合っています。Customersのコレクションは単なるコレクションです。
Ibrahim Malluf 2016

111

集約ルートは、単純なアイデアの複雑な名前です。


一般的なアイデア

適切に設計されたクラス図は、その内部をカプセル化しています。この構造にアクセスするためのポイントはと呼ばれ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ます。


集約ルートは複数のクラスをカプセル化します。メインオブジェクトを介してのみ階層全体を操作できます。


17
この例は好きですが、お客様がエンジンを参照する必要があるシナリオを見つけるのに苦労しています。EngineはCarの後ろにカプセル化する必要があるようです。これについて少し詳しく説明していただけますか?
Emragins、2015年

私の意見では、エンジン自体は車固有のモデル、たとえば3000ccエンジンを搭載したBMWシリーズ5内にある必要があります。このモデリングでは、エンジンは自動車のコンポーネントです。
Parama Dharmika、2016年

1
@ParamaDharmika確かに、そのようにモデル化できます。それは、自動車がいかに「高度」であるかによって異なります。基本モデルでは、彼はcar集約ルートにアクセスできる必要があります。図面のような状況を許可することもできます。正しい解決策は、アプリケーションのビジネスモデルによって異なります。場合によって異なります。
Marcin Szymczak

1
@MarcinSzymczak正解、ソリューションがドメインモデル自体に依存することについてこれ以上同意できない
Parama Dharmika

実際、ホイールはタイヤ(およびその他のパーツ)を含む集合体です。ホイールアグリゲートを介してのみホイールアグリゲートにアクセスできるようにする必要があるルールの場合、エンジンも車ルートアグリゲート内に含まれ、車の外部からはアクセスできません。それはCarインスタンスの領域です。車の所有者(顧客)は、自分の車のコンテキスト以外ではエンジンを参照しません。
Ibrahim Malluf 2016

35

コンピューターエンティティがあるとします。このエンティティも、ソフトウェアエンティティとハードウェアエンティティなしでは生きられません。これら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がありません)。これは単なる例として考えてください。


6
where T : IAggregateRoot-これは私の日を作った
クリスティアンE.

言葉遣いは少し矛盾しています。これを理解しようとすると私は混乱します。あなたはコンピュータが集合体であると言っていますが、それからルートは集合体の中にある母船エンティティであると言っています。それでは、この例では、集合体内の「母性」エンティティはどれですか。
Sinaesthetic 2016年

未来からのご挨拶!男が意味することは、コンピュータ自体が集約ルートであり、コンピュータとその中のすべてが集約であるということです。さらに明確に言えば、ケース自体が集約ルートであり、コンピュータ全体が集約です(「コンピュータを構成するすべてのコレクション、たとえばRGB照明、ハードウェア、電源、OSなど)
ケンパチキャプテン

MicrosoftのドキュメントのIAggregateRoot技術ショーアップ:docs.microsoft.com/en-us/dotnet/architecture/microservices/...
サミュエル・ダニエルソン

16

データベースファーストのアプローチに従う場合、ルートは通常、1対多の関係の片側のテーブルです。

最も一般的な例は人物です。一人一人が多くの住所、1つ以上の支払い伝票、請求書、CRMエントリなどを持っています。常にそうであるとは限りませんが、9/10倍です。

現在、eコマースプラットフォームに取り組んでおり、基本的に2つのルートがあります。

  1. お客さま
  2. 販売者

顧客は連絡先情報を提供し、トランザクションを割り当て、トランザクションはラインアイテムを取得します。

売り手は製品を販売し、連絡先を持ち、私たちについてのページ、特別オファーなどを持っています。

これらは、それぞれCustomerリポジトリとSellerリポジトリによって処理されます。


8
データベースファーストのアプローチに従う場合は、ドメインドリブンデザインを実践しておらず、データドリブンデザインを実践しています。
Sinaesthetic

5
これは、人々が問題を解決したり、学んだりするために訪れるQ&Aフォーラムです。定義により、DDDは他の何よりも考え方であり、多くの人にとって混乱を招くので、設計方法論の潜在的な融合を軽減するためにDDDを学んでいる人たちに対してコメントが行われたことを確認しました。
Sinaesthetic

12

ダイナ:

リポジトリーのコンテキストでは、集約ルートは親エンティティーのないエンティティーです。これには、その存在が親のアイデンティティーに依存しているゼロ、1つまたは多数の子エンティティが含まれます。これは、リポジトリにおける1対多の関係です。これらの子エンティティはプレーンアグリゲートです。

ここに画像の説明を入力してください


1
それで、もしあなたが自動車の売り手なら、自動車はそれ自体で集合的な根となるでしょうか?まだ顧客がいない多くの車を所有できるため
JorgeeFG 2017年

2
@JorgeeFG本当の答えは、誰もまったく何の手がかりもないということです。非常に多くの矛盾する情報が点在しています。
Mardoxx

3
子エンティティは集約ではなく、たまたま、集約ルートが制御する集約のメンバーであるエンティティです。「集合体」とは、エンティティーの論理グループです。
Sinaesthetic

@JorgeeFGそれは本当にあなたが設計している境界のあるコンテキストに依存します。あなたが車の売り手なら、カーショップのようなものが集合ルートになり、その下には車が続きます...
jokab

8

壊れたリンクから:

アグリゲート内には、アグリゲートルートがあります。集合ルートは、集合内の他のすべてのエンティティおよび値オブジェクトの親エンティティです。

リポジトリは集約ルート上で動作します。

詳細については、こちらご覧ください


4
ありがとうございました。それは間違いなく、私が頻繁に遭遇した最も一般的でイライラする壊れたリンクです。
ダイナ

また、言い回しは逆のようです。ルートはどのようにてアグリゲート内になり、同時に親になることができますか?
Sinaesthetic 2015年

1
集約ルートはルートクラスです。プレーンアグリゲートは常にアグリゲートルート内に含まれます。上記の図を使用すると...顧客は集約ルートです。お客様は1台以上の車を所有できます。車は顧客との関係で集合体です。車にはエンジンがあります。エンジンは、Car Aggregateに含まれるAggregateです。顧客を集約ルートにするのは、車またはそのコンポーネントへのアクセスは常に車を所有する顧客を通じて行われるというモデルの前提です。
Ibrahim Malluf 2016

8

集合とは、何かを集めることを意味します。
ルートは、ツリーの最上位ノードのようなもので、そこから<html>Webページドキュメントのノードのようなすべてにアクセスできます。
ブログのアナロジー、ユーザーは多くの投稿を持つことができ、各投稿は多くのコメントを持つことができます。したがって、ユーザーをフェッチした場合、それはrootとして機能し、すべての関連する投稿とそれらの投稿のコメントにアクセスできます。これらはすべてコレクションまたは集約されているといわれます


1

Aggregateは、不変条件を保護し、アクセスの集計ルートを制限することで一貫性を強制する場所です。集計はデータベースの関係ではなく、プロジェクトのビジネスルールと不変式に基づいて設計する必要があることを忘れないでください。リポジトリを挿入しないでください。クエリは許可されません。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.