大きな集合根を処理する方法は?


11

DDDを学習していますが、回答よりも多くの質問があります。

膨大な数のファイルを含むディレクトリのモデルを考えてみましょう。
ここに私がそれを見る方法があります:

ディレクトリは集約ルートです。
このエンティティには、追加または名前変更されたときにファイル名の一意性をチェックする検証ロジックが必要です。また、ファイルエンティティには「SetName」ロジックが含まれており、ドメインイベントを介してディレクトリに名前の変更を通知します。
しかし、ディレクトリはどのように機能するのでしょうか。
すべてのファイルをメモリにロードできるとは限りません。この場合、ファイルリポジトリには、名前の一意性をチェックするためのアドホックロジックが必要ですか?それは実行可能な決定だと思います。
ただし、現在コミットされていないトランザクションで一部のファイルがすでに追加または名前変更されている場合はどうなりますか?(それを禁止するものはありません。トランザクション境界は、ビジネスロジックに関連して外部で設定されます)。おそらくリポジトリは、メモリ内の状態と永続化された状態の両方を考慮する必要があります(これらの状態をマージすることは簡単な作業ではありません)。

したがって、すべての子を持つルートの集合体がメモリに収まる場合、すべてが正常です。そして、すべてのエンティティを具体化できないとすぐに問題が発生します。

そのような場合の取り組みを教えてください。全く問題ないのかもしれませんが、それは私の誤解です。


1
「FileInfo」だけでなく、すべてのファイルとそのコンテンツをロードする必要があると思うのはなぜですか。
陶酔感14

@Euphoric。まあ、それは時々不可能です。とにかく別の問題があります。現在のトランザクション内で変更されたFileInfoおよび対応するFileエンティティの一貫性を提供する方法は?おそらくCQRSがこの問題に対処します...まだ見ていません。
Pavel Voronin 14

1
DDDはプログラミング手法ではなく、設計手法であることを理解しておくと役に立ちます。コーディング方法論のように扱う人が多すぎます。「集約ルート」などの用語は、実際にはプログラミング技法についてあまり話さないのに、技術的な重みの印象を与えるため、問題を悪化させます。プログラミング手法はDDDであまり変わりません。DDDはコードとアーキテクチャを通知しますが、それでもコードとアーキテクチャは分離しています。
ロバートハーベイ14

@RobertHarvey DDDにはもっと複雑なプログラミング技術が必要なようです。少なくともそれがコーナーケースになると。私はDDDを、ビジネスロジックを背後で暗黙的に機能する不可避のインフラストラクチャコードから分離(およびローカライズ)する方法として主に扱います。私にとってDDD = good OOD +暗黙のインフラストラクチャ。DDDに関して私が持っている質問のほとんどは、最後の部分に関連しています。
Pavel Voronin 2014

2
なぜ「トランザクション境界はビジネスロジックに関連して外部的に設定される」と言うのですか?集約ルートの義務は、トランザクション境界を維持することです。また、ファイルの内容をロードする必要はありません。あなただけのメタデータをロードすることができます。
Esben Skov Pedersen 2014

回答:


20

私の答えは、Vaughn VernonのImplementing Domain Driven Designの素晴らしい本に偏っています(必読)

1.小さな凝集体を好む。

私はあなたのドメインをモデル化するんなら、私は、モデルとなるDirectory骨材として及びFile他の骨材として。

2. IDで集計を参照します。

したがってDirectoryFileId値オブジェクトのコレクションを持ちます。

3.工場を使用して集計を作成します。

単純なケースでは、ファクトリメソッドで十分な場合がありますDirectory.addFile(FileName fileName)。ただし、より複雑なケースでは、ドメインファクトリを使用します。
ドメインファクトリはfileNameFileRepositoryおよびUniquefileNameValidatorインフラストラクチャサービスを使用して、が一意であることを検証できます。

なぜFile別の集合体としてモデル化するのですか?

からDirectories作られていませんのでFiles。a Fileは特定のに関連付けられていDirectoryます。また、何千ものファイルがあるディレクトリを考えてください。ディレクトリがフェッチされるたびにこれらすべてのオブジェクトをメモリにロードすると、パフォーマンスが大幅に低下します。

ユースケースに応じて集計をモデル化します。ディレクトリに2〜3個を超えるファイルが存在しないことがわかっている場合は、それらをすべて1つの集約としてモデル化できますが、私の経験では、ビジネスルールは常に変化し、モデルが変更。

必須の読み取りVaughn Vernonによる効果的な集計デザイン


2
実際、実際のディレクトリ実装は通常、このように実装されていることに注意してください(個別の集合体、それらのIDで参照)。たとえば、「ファイル」はinode、UNIXシステムではディレクトリから単に参照されます。
Alexander Langer 2014年

1
ようやくおすすめの本を読みました。素晴らしい本、ありがとう。それにもかかわらず、それはまだ完全に明確ではありません。にはFile、指定された名前を持つ1つだけが存在できますDirectory。つまりDirectory、不変:名前の一意性があります。少なくともにとっては重要ですが、Directoryでは重要ではありませんFile。実際、@ AlexanderLangerは正しいです。「ファイル」は多くの「フォルダ」から参照できます。そして、名前はおそらくFileそれ自体ではなく、この参照のプロパティです。OK。次に、名前変更機能はに属しますが、Directory何千もの参照IDを保存することはお勧めできません。
Pavel Voronin

そして、たとえそうしたとしても、名前に対してチェックを行う必要があります。ここからは、フォルダーリポジトリにメソッドを作成するのが合理的ですbool ContainsFileOfName(int folderId, string fileName)。その後、「名前の変更」メソッドのシグネチャは次のようになります。(リポジトリをラップする)void Rename(int fileId, string newName)一部の内部IFolderServiceが解決され、そのような名前が存在するかどうかが尋ねられます。
Pavel Voronin

1

これはそれ自体DDDの質問ではありません。ここでの主な質問は、同期コンテキスト(ここでは集約ルート)に関するものです。

トピックに戻る:ディレクトリは、ファイル名のいくつかの同期オブジェクトをブロックし、指定されたファイル名が許可されているかどうかを確認します。これは、最悪の場合O(n)です。


1

デザインを変更しようとする人もいますが、ARが単純なオブジェクトの大きなリストを保持する必要が常にあります。そして、それらをメモリに格納することは、パフォーマンスの観点からは最善のことではありませんが、そのような場合に必要なことは、トランザクションの境界を保持することだけです。簡単な解決策は次のとおりです。

  1. フォルダのARをシンプルに保ち、バージョン列を配置します。
  2. 各ファイル(行としましょう)が集​​約ルートを参照するようにします。つまり、フォルダーのIDを保持します。
  3. 常に、ARを介して、名前の変更、追加、削除などのファイルの変更を実行します。つまり、ファイルを追加する場合は、ARをロードし、ARのメソッドを使用して変更を行います。リポジトリパターンを使用している場合、addFile()は新しいファイルを作成し、フォルダーのバージョンを変更します。それらをUoWとして保存します。他の誰かがARを変更した場合、バージョン列(ARバージョン)が原因でエラーが発生します。
  4. ファイルの編集や名前の変更など、ファイル自体に対する変更は、ARを介して行う必要があります。そのため、バージョンはARに保持されます。これは、所有するARを除いて、ファイルを変更する他の実行パスがコードに本質的にないことを意味します。

いくつかの制限:

  1. ファイルは1つのARのみに属している必要があります。そうでない場合は、フォルダ->ファイルの関係を、ファイル自体ではなく包含としてモデル化します。
  2. UoWでこの変更を行わない限り、つまり同じトランザクションで、1つのファイルをあるフォルダーから別のフォルダーに移動することはできません。これは特別なケースです。2つのコマンドで終わる1つの要求を送信する必要があるため、両方のARが変更され、それぞれに2つの新しいバージョンと、おそらく2つのイベント(ファイルの削除、ファイルの追加)があり、これは少しです2つのARのイベントの順序を維持する必要があるため、トリッキーです。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.