問題タブ [aggregateroot]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
design-patterns - エンティティがアグリゲートのルートになる場合、アグリゲートルートはルートエンティティの既存のIDを使用しますか、それともARは独自のIDを作成しますか?
ドメイン駆動設計(DDD)では、エンティティは常に独自のIDを持っています。
DDDを読んでいると、エンティティと集約ルートの間の「一意のアイデンティティ」の概念が混在しているように見えるステートメントと例を見てきました。例によっては、次のことを意味する場合があります。
- 以下のインターフェースの1つだけが必要です。
また
- 両方必要です。
「EricEvanstypeDDD」に関しては、どちらのアプローチが「正しい」か知りたいです。
たとえば、エンティティがこのインターフェイスを実装し、このメソッドが呼び出されたときにGUIDを返すとします。
以下のものも必要ですか?
アグリゲートルートは、ルートエンティティのID(IdThatIsUniqueForThisEntityObject)とは別の独自のID(IdThatIsUniqueForThisAggregateRootObject)を表すことができるように、上記のようなインターフェイスを実装する必要がありますか?
または、集約ルートは、ルートエンティティ(IdThatIsUniqueForThisEntityObject)を使用して、集約ルートの一意のIDを表す必要がありますか?
nhibernate - DDD を使用して構築された公開 Web サイトは、1 つの主要な集約ルートを持たないようにする方法
一般にアクセス可能な Web サイトを作成する際に、ドメイン駆動設計を使用しようとしています。私が抱えている問題の 1 つは、モデルの集約ルートがどうあるべきかを理解しようとすることです。私は、どのオブジェクトがエンティティ オブジェクトで、どのオブジェクトが値オブジェクトであるかについてかなり良い考えを持っています。
私のサイトは、ほとんどの公開サイトと同様に、すべてのユーザーがサイトに保存されているすべての情報を閲覧できるわけではありません。代わりに、自分が所有する情報しか見ることができません。私のサイトの場合、ユーザーは他のユーザーと共有できる「プロジェクト」を作成します。それでも、ユーザーは自分が作成したプロジェクトまたは参加を招待されたプロジェクトの情報しか見ることができません。私のモデルの他のすべてのオブジェクトはプロジェクト内に存在し、プロジェクトが削除された場合、それに含まれるすべてのオブジェクトも削除する必要があります。
これは、1 つのメインの「Project」集約ルート タイプと 1 つの「ProjectRepository」リポジトリを用意する必要があるということですか? サイトのページがリクエストされるたびにプロジェクト全体をロードするのは効率が悪いように思えます。実際には、要求されたプロジェクト内のアイテムのみを遅延ロードする NHibernate を使用しているため、これはそれほど問題ではありません。それでも、サイトの効率が遅延読み込みを伴う ORM の使用に大きく依存するようにするのは、悪い設計のように思えます。
これが、私の質問をより明確にすることを願っている更新です。
まず、プロジェクト タイプがモデルの集約ルートであるべきかどうかを理解しようとしています。プロジェクトは単独で存在できますが、レポートはプロジェクト内に存在する必要があります。プロジェクトが削除された場合、対応するレポートを削除する必要があります。これは、Project が集約ルートになる可能性がある、または集約ルートになる必要があることを意味しますか? これはよくわかりません。
プロジェクトが集約ルートの場合、レポートは正しくないはずですか? 私が理解しているように、ルートは DDD にネストされるべきではありません。さらに、リポジトリから取得できるのは集約ルートのみです。したがって、Report が集約ルートでない場合は、ReportsRepository を持つべきではなく、ProjectsRepository から取得したプロジェクトを介してのみ Report にアクセスする必要があります。そのため、ページが 1 つのレポートからのデータのみを必要とする場合でも、レポートを取得するには ProjectRepository からプロジェクト全体を読み込む必要があります。
さらに、プロジェクトがレポートを含む集約ルートである場合、ProjectRepository からプロジェクトを削除すると、含まれるレポートを削除するように設定することもできます。それでも、プロジェクトとレポートの両方が集約ルートである場合、プロジェクトが削除されたときに ProjectRepository がレポートを削除できないようにすると、集約間の境界が壊れますか? 集約ルートとそれに対応するリポジトリは、互いに独立して動作するはずではありませんか?
orm - 集約ルートをバイパスして個々のモデルを編集する
これは別の質問へのフォローアップです: Bypassing Aggregate Root。
この質問の作成者は、彼の例で集約ルートをバイパスすることが許容されるかどうかを尋ねました。同じ質問がありますが、使用例が異なります。
私たちの Web アプリケーションには、集約ルートに属するすべてのアイテムを編集できるバックオフィスがあります。
- 製品 (集約ルート)
- オプション
- オプション項目
等
製品はすべてのオプションをバッチで作成するわけではないため、集計ルート内の各エンティティを個別の画面で 1 つずつ編集します。ステートレス システムにいるため、URL パラメーターで処理したいエンティティを一意に識別する必要があります。id
これは、たとえば、ルートから参照するのではなく、その に基づいてオプションをフェッチして編集することを意味します。
IMHO、それぞれのリポジトリを用意して、次のことを行う方が理にかなっています。
次のようなものではなく:
それは、ドメイン駆動設計の集約ルートの概念を壊しているのでしょうか? その場合、正しい方法を教えていただけると大変ありがたいです。
domain-driven-design - 集約ルート間の関係と制約をどのように適用する必要がありますか?
DDDモデルの2つの集約ルート間の参照間の関係についていくつか質問があります。以下に示す典型的な顧客/注文モデルを参照してください。
まず、集計の実際のオブジェクト実装間の参照は、オブジェクト参照ではなく、常にID値を介して行う必要がありますか?たとえば、注文の顧客の詳細が必要な場合は、顧客を直接返すようにOrderオブジェクトを設定するのではなく、CustomerIdを取得してICustomerRepositoryに渡して顧客を取得する必要がありますか?顧客を直接返すと、モデルに対するコードの記述が簡単になり、NHibernateのようなORMを使用している場合は、セットアップがそれほど難しくないため、混乱しています。それでも、これが集約ルート/リポジトリ間の境界に違反することになると私はかなり確信しています。
次に、2つの集約ルートに対して、削除関係のカスケードをどこでどのように実施する必要がありますか?たとえば、顧客が削除されたときに、関連するすべての注文を削除したいとします。ICustomerRepository.DeleteCustomer()メソッドはIOrderRepostioryを参照するべきではありませんか?それは、アグリゲート/リポジトリ間の境界を壊しているように見えますか?代わりに、IOrderRepositoryとICustomerRepositoryの両方を参照する顧客とそれに関連する注文の削除を処理するCustomerManagmentサービスを用意する必要がありますか?その場合、顧客を削除するためにリポジトリではなくサービスを使用することを人々が知っていることをどのように確認できますか。それは、モデルを正しく使用する方法について彼らを教育することだけですか?
domain-driven-design - ドメイン駆動設計におけるルートの複雑さの集約
集合体の複雑さの線引きはどこにあるのでしょうか? 明確にするために、集計に ObjectC のリストを持つ ObjectB のリストを持つ ObjectA のリストがある場合、集計は ObjectC の取得を担当する必要がありますか? それとも、この複雑さを階層内のいくつかのレベルに抑えるために、別の集計を作成することを検討する必要がありますか?
.net - リポジトリパターン-集約ルート
エンティティフレームワークデータモデルのどこに集計ルートがあるかを頭に入れようとしているので、作成する必要のあるリポジトリがわかります。
リレーショナルデータベースの用語で少し話をすると、ExceptionGroupオブジェクトとExceptionオブジェクト(system.exceptionではありません!)があります。例外はExceptionGroupに属し、ExceptionGroupなしでは存在できません。
各オブジェクトのリポジトリ、または両方のメソッドを含む単一のリポジトリが必要ですか?単一のリポジトリがある場合、メソッドは次のようになります...
c# - EntityFramework4.1と親子関係を持つリポジトリパターン
リポジトリパターンとはまだ混乱しています。このパターンを使用する主な理由は、ドメインからEF4.1固有のデータアクセス操作を呼び出さないようにするためです。IRepositoryインターフェースからジェネリックCRUD操作を呼び出したいと思います。これにより、テストが容易になり、将来データアクセスフレームワークを変更する必要が生じた場合でも、多くのコードをリファクタリングすることなく変更できるようになります。
これが私の状況の例です:
Group
データベースに、、、Person
およびの3つのテーブルがありますGroupPersonMap
。GroupPersonMap
はリンクテーブルであり、主キーGroup
とPerson
主キーのみで構成されます。VS2010デザイナーで3つのテーブルのEFモデルを作成しました。EFは、リンクテーブルであると想定するのに十分賢いGroupPersonMap
ので、デザイナーには表示されません。EFで生成されたクラスの代わりに既存のドメインオブジェクトを使用したいので、モデルのコード生成をオフにします。
EFモデルに一致する私の既存のクラスは次のとおりです。
私は次のような一般的なリポジトリインターフェイスを持っています:
および一般的なEFリポジトリ:
Group
ここで、既存のものを既存のものにマップしたいとしますPerson
。私は次のようなことをしなければならないでしょう:
ただし、EFは新しいと見なし、データベースに再入力しようとするため、これは機能しません。Person
これにより、主キー制約エラーが発生します。のメソッドを使用して、データベースにすでに存在することをEFに通知する必要があるため、テーブルとテーブルの間にマップを作成するだけです。INSERT
Person
DbSet
Attach
Person
Group
Person
GroupPersonMap
したがってPerson
、コンテキストにアタッチするにはAttach
、IRepositoryにメソッドを追加する必要があります。
主キー制約エラーを修正するには:
修理済み。Group
ここで、グループ/個人マップを作成するたびにデータベースで更新される別の問題に対処する必要があります。これは、私のEFRepository.Update()
メソッドでは、エンティティの状態が明示的にUnchanged Group`に設定されてModified'. I must set the Group's state to
いるため、so the
テーブルが変更されないためです。
これを修正するにはUpdate
、ルートエンティティを更新しない何らかのオーバーロードをIRepositoryに追加する必要がありますGroup
。この場合、次のようになります。
UpdateメソッドのEF4の意味は、次のようになります。
私の質問は:私はこれに正しい方法でアプローチしていますか?EFとリポジトリパターンを使い始めると、リポジトリはEF中心に見え始めています。この長い投稿を読んでくれてありがとう
orm - 集計内のエンティティを更新する
SO: How update an entity inside Aggregateに関する同様の質問を読んでいましたが、ユーザー インターフェイスが集約内のエンティティとどのようにやり取りする必要があるかはまだわかりません。
esUser
がたくさんある ,があるとしましょう。Address
ユーザーは集約ルートですが、アドレスは集約内にのみ存在します。
Web インターフェイスで、ユーザーは自分のアドレスを編集できます。基本的に、何が起こるか:
- ユーザーの Web インターフェイスにアドレスのリストが表示されます。
- アドレスをクリックすると、次のページにリダイレクトされます。
edit-address?user=1&address=2
- このページで、彼はこの住所を変更できるフォームを取得します。
集約ルートをバイパスすることにしましたが、これは簡単です。
- を直接ロード
Address
しますId
- 更新してから保存します
DDD の方法で実行したいので、さまざまな解決策があります。
Id でこのアドレスを取得するようにユーザーに依頼します。
address = user.getAddress(id);
address.setPostCode("12345");
address.setCity("New York");
em.persist(user);
このアプローチの問題点は、IMO によると、集約ルートがまだアドレスの処理をあまり制御できないことです。それへの参照を返すだけなので、集約をバイパスすることと大差ありません。
または、集約に既存のアドレスを更新するように指示します。
user.updateAddress(id, "12345", "New York");
em.persist(user);
これで、集約はこのアドレスの処理を制御できるようになり、アドレスの更新に必要なアクションを実行できます。
または、 Address を値オブジェクトとして扱い、を更新せず
Address
に、削除して再作成します。user.removeAddress(id);
address = new Address();
address.setPostCode("12345");
address.setCity("New York");
user.addAddress(address);
em.persist(user);
この最後の解決策は洗練されているように見えますが、Address をエンティティにすることはできません。次に、たとえば集約内の別のビジネス オブジェクトがそれを参照しているなどの理由で、それをentity として扱う必要がある場合はどうなるでしょうか。
集計の概念と、それが実際の例でどのように使用されているかを正しく理解するために、ここで何かが欠けていると確信しているので、遠慮なくコメントをお寄せください!
c# - リポジトリパターンでサブエンティティのページングを処理するにはどうすればよいですか?
私はドメイン駆動型の設計を学んでいます。私は現在、DDDを使用して設計するC#で簡単なアプリケーションを作成しようとしています。このアプリケーションには、0..n個のサブエンティティBを含むことができる集約ルートAがあります。これは、次の線に沿ったもので表すことができます。
リポジトリ付き:
ただし、特定のAインスタンスのBサブエンティティを表示するときにページングを追加したいと思います。どうすればいいですか?私が思いつくことができる最善の方法は、AとARepositoryを次のようなものに変更することです。
それは確かに機能しますが、私はドメインモデルのシンプルさと優雅さを失います。
リポジトリパターンを使用してサブエンティティのページングを処理する方法のベストプラクティスは何ですか?特定のライブラリなどを使ってこれに対処する方法を探しているのではなく、「パターンレベル」で対処する方法を探しています。
language-agnostic - DDD: ID によって集約ルート内のエンティティを参照する
集約 root内にあるエンティティーを参照する適切な方法を見つけることに行き詰まっています。URL パラメーターからのIDしか取得していない場合です。値オブジェクトに焦点を当てた前の質問をしたので、ここで別の例から始めます。
OrderLine
an内の anを変更したいとしましょうOrder
:
- ユーザーは、注文の概要とそのすべての注文明細を確認できるページに移動します。
- ユーザーは、注文明細の横にある編集ボタンをクリックします。
- 彼は指示されます
edit-order-line?orderId=x&orderLineId=y
OrderLine の数量を更新する必要がある場合は、次のようにします。
しかし、ID によって自分自身の一部を取得する責任をオーダーに任せるという考えにはあまり満足できません。この件に関する私の見解は、ドメイン内ではオブジェクトとだけ話すべきであり、ID とは決して話すべきではないということです。Id はユビキタス言語の一部ではありません。ID はドメインの外、たとえば Controller 内に存在する必要があると思います。
次のようなものを使用すると、より自信が持てます。
Entity Manager と直接対話するという考えも好きではありませんが。リポジトリと集約ルートの責任をバイパスしているように感じます (潜在的に、OrderLine と直接対話できるため) 。
それをどのように回避しますか?