0

私は DDD の概念を学んでおり、理解を深めるために実際の例に取り組んでいます。

集約にはルート エンティティを介したエントリ ポイントが 1 つだけ必要であり、集約にはリポジトリが 1 つだけ必要であることを知っています (完全に間違っていると理解した場合は修正してください)。

ここで、特定の種類の消耗品があり、これらの消耗品が配送センターから送られてくるとします。特定のタイプの消耗品の発送は、その数量によって異なります。つまり、消費者の 1 人がタイプ A と B のクリティカル数量 10 を持っていて、それらのアイテムの数量が 10 を下回った場合、配送センターはタイプ A と B の消耗品を送ります。ここでは、送信者と消費者の両方が、送信されたパッケージがどこにあるか、またはそれが配達されたか、またはまったく送信されたかを追跡したいと考えています。

ここでは、エンティティとして次のものがあります。

  1. 消耗品
  2. 消耗品の種類
  3. 消耗品アクティビティ
  4. パッケージ
  5. パッケージアイテム
  6. 消費者

最初の 3 つのエンティティについて混乱しています。どのエンティティを集約ルートにする必要がありますか? ざっと見てみると、消耗品が有力な候補のように見えますが、一方で、すべての消耗品を気にしているわけではなく、その量だけに関心があります。タイプ A の 10 個の異なる消耗品を記録するのではなく、活動に応じて数量が変化するタイプ A の記録しかありません。この時点で、消耗品エンティティは冗長に見えますが、アクティビティを見るだけで数量を導き出すことができます。たとえば、ゼロから開始します。

  1. センタークリエイト「タイプA」 10
  2. センタークリエイト「タイプB」 20
  3. センター送信「タイプ A」 5 ConsumerId=25
  4. センター送信「タイプ B」 15 ConsumerId=25
  5. ConsumerId=25 「タイプ A」5 を受信
  6. ConsumerId=25 「タイプ B」15 を受信
  7. ConsumerId=25 「タイプ A」を消費 3
  8. ConsumerId=25 「タイプ B」を消費 1
  9. ConsumerId=25 「タイプ A」を消費 2

ここでは、中央に 5 つのタイプ A および B の消耗品があり、現時点では id 25 の消費者にはタイプ A および 14 のタイプ B の消耗品があることがわかります。

もちろん、これは効果的なアプローチではありませんが、より多くの活動が行われた後、消耗品の数量を導き出すのに時間がかかるため、消費者と流通センターの両方に対して、すべての消耗品タイプの静的な数量フィールドが必要です。現在の量を一度に。

私が混乱している理由を理解していただければ幸いです。消費可能なエンティティはルート エンティティのように見えますが、実際にはエンティティではない場合、ルート エンティティには適合しません。

この設計に関する改善点や、顧客製品注文注文ラインの悪夢に限定されない推奨事項をさらに読むことを提案できる人はいますか?


編集: Consumable および ConsumableType との関係は何ですか? ConsumableType で CRUD 操作を実行したい (ユーザーに新しいタイプを追加、変更、または削除させる) が、ルート エンティティが Consumable である場合はどうすればよいでしょうか。DDD でデータの整合性を維持するには、ルート エンティティ リポジトリ以外のリポジトリをロードしないでください。

編集 2: Product エンティティとその Category エンティティについて考えてください。製品はルート エンティティのようですが、製品はカテゴリなしでは存在できないことがわかっています。では、Category エンティティはルートですか? その場合、DDD の規則に従って、トラバースによってのみ製品にアクセスできます。しかし、私たちのコンテキストでは、製品が私たちの焦点です。次に、製品集計とカテゴリ集計の 2 つの集計があるとします。しかし今回は、このカテゴリを持つ製品を削除せずにカテゴリを削除する可能性があるため、データの整合性に違反しています。そのため、私は多くのことを混乱させており、適切な解決策を見つけることができませんでした。

4

1 に答える 1

2

最初の 3 つのエンティティについて混乱しています。どのエンティティを集約ルートにする必要がありますか?

この例を 2 つ以上の別個の境界付けられたコンテキストに分割する必要がある可能性はありますが、ほとんどの場合、集約は Package であると言うつもりです。(作成と注文のフルフィルメントは自然な境界です)

Consumable および ConsumableType との関係は何ですか?

それは、境界付けられたコンテキストによって異なります。「A」または「B」で指定されている以外の ConsumableType についてこれ以上知らなくても、Consumable の値オブジェクトである可能性が高いと言わざるを得ません。

ConsumableType で CRUD 操作を実行したい (ユーザーに新しいタイプを追加、変更、または削除させる) が、ルート エンティティが Consumable である場合はどうすればよいですか?

これは、まったく別の境界付けられたコンテキスト (一部のマネージャーのコンテキスト、またはモデル化している一般的なワークフローに含まれないもの) である可能性が高く、このコンテキストについてさらに調査することが提案されています。

【別例】

では、Category エンティティはルートですか?

集約ルートは、コンテキスト内のユーザーが対話するものです。この例ではコンテキストを完全に説明していないため ALOT であると仮定すると、ユーザーが最も関心を持っているのは製品であるため、製品が集約ルートである可能性が最も高くなります。上記の例と同じように、Product には、割り当てられたカテゴリをロードするリポジトリがあります。この場合、カテゴリまたは階層のリストの読み込みは、特定のエンティティ インスタンスに属していないため、ドメイン サービスによって最適に処理されます。

[もう一つの例]

あなたの最初のケースでは、例えばシステム管理者はどのようにして利用可能なすべてのフォントの色を一覧表示したり、新しい色を追加したりできますか?

繰り返しますが、システム管理者のコンテキストは、フォントの色を選択するユーザーと同じコンテキストではありません。各コンテキストは単一のワークフローです。複雑なワークフローでは、同じコンテキストに複数のユーザーが存在する可能性がありますが、管理者が実行する可能性のある CRUD 操作などの単純なワークフローの場合、通常、このタイプのワークフローには 1 つのロールしかありません。システム管理者の下では、AvailableFontColor は、コンテンツ装飾オプション管理境界コンテキスト内の Color 値プロパティを持つエンティティである可能性があります。

この設計に関する改善点や、顧客製品注文注文ラインの悪夢に限定されない推奨事項をさらに読むことを提案してくれる人はいますか?

境界付けられたコンテキストと、ビジネス ドメインをモデル化する際に境界付けられたコンテキストが最も有用な (そして時には最も妨げとなる) ツールの 1 つである理由について、さらに学ぶことをお勧めします。また、これが 1 週間以内に科学的に完成することを期待しないでください。

私は 8 年以上にわたってさまざまな手法を使用してソフトウェアをモデリングしてきましたが、何かを正しくモデリングしたかどうかを判断するのにまだ苦労しています。DDD の最大の利点の 1 つは、おそらく最初から正しくモデル化できないという事実を受け入れるよう促すことです。最初からドメインを完全に理解していなかったために、元のモデルの周りに 15 の異なる複雑なクラッジで終わるよりも。

于 2013-01-09T21:26:25.547 に答える