9

私が典型的なエンティティCarを持っているとしましょう

class Car : Entity
{
    public double MaxSpeed { get; set; }
    public Color Color { get; set; }
    /* ... */
}

このエンティティは、私のドメインモデルでは、Aggregateのルートエンティティになります。

今、私が車を専門にしているとしましょう。私はフェラーリを作成します、そしてフェラーリの幸せな所有者はニックネームでそれらを呼ぶのが好きです:

class Ferrari : Car
{
    public string Nickname { get; set; }
}

別のエンティティであるCompanyエンティティがあるとします。これは、別のAggregateのルートエンティティになります。エンティティPersonに代表される、会社で働いている多くの人々がいます。人は車を持っているかもしれません。しかし、会社の社長は通常非常に裕福であり、この種の人々はフェラーリスを持っています:

class President : Person
{
    public Ferrari Ferrari { get; set; }
}

この状況では、別のアグリゲートのルートエンティティのスペシャライゼーションであるフェラーリへの参照を保持している、CompanyAggregateにあるエンティティPresidentがいます。

これはDDDの観点から正しいですか?ルートエンティティ自体の特殊化を同じ集合体のルートエンティティと見なすことができますか/すべきですか?つまり、私が説明したドメインでは、エンティティFerrariはCar Aggregateのルートエンティティでもありますか(FerrariもCarであるため)?


ここで、このモデルをデータベースに永続化する必要があるとしましょう。私の質問は、使用するOR/Mフレームワークに依存しないと思います。

車を保持するテーブルをどのように作成すればよいですか?「CarType」列(可能な値:「Car」、「Ferrari」)とnull許容のニックネーム列を持つ単一のテーブルCarsを作成する必要がありますか?

または、車用のテーブルとフェラーリ用のテーブルを作成する必要があります。後者のPKは車のFKです。

ありがとう!

4

3 に答える 3

4

モデルが複雑になり始めるとすぐに問題が発生するため、継承を使用してドメインをモデル化しないでください。

社長は単に個人の役割であり、個人は複数の役割を持つことができます。大統領は 1 つの役割しか与えられなかったかもしれませんが、それは間違った例を選んだことによる単純な偶然です。

フェラーリも車から受け継ぐべきではありません。フェラーリの例では明らかではありません。なぜなら、彼らは 1 種類の車しか製造していないため、会社がバン、セダン、ハッチバック、トラックなどの多くの種類を製造していると考えているからです。car クラスから継承するすべてのタイプのクラスを作成する必要があるでしょう。では、各タイプを継承する 5 つのトヨタ クラスを作成しますか? そのような...

Car -> Sedan -> ToyotaSedan
Car -> Truck -> ToyotaTruck
Car -> Hatchback -> ToyotaHatchback

それはばかげているでしょう。

免責事項:私は車について何も知りません。でも...

ドメインのモデル化に継承を使用しないでください。これまで。

継承なしで試してみると、ドメインを永続化する方法も明らかになります。

于 2009-08-29T20:21:44.500 に答える
4

一般に、ルート集合体の境界を越える場合、他のルート集合体の ID の参照のみを許可します。次に、その ID を使用して、リポジトリ内の他の集計を検索します。

したがって、あなたのケースでは、大統領に車の ID を持たせ、大統領の車に何かをする必要がある場合は、車の ID を使用してリポジトリに移動し、車を取得します。大統領は、車自体への言及を持っていません。

さて、そのフェラーリについて。標準の DDD 用語でそれを強制するのはちょっと難しいです。通常、社長への車の割り当てに何らかの検証を行います。または、大統領専用の CarBuyingService があり、確実に正しく購入できるようになっているかもしれません。通常、DDD の特殊化では、それ自体がルート集合体ではありません。

于 2009-08-29T20:23:18.727 に答える
3

これらのエンティティの具体的なタイプを作成することで、システムの柔軟性を大幅に失い始めていると思います。あなたが暗示している関係のタイプは、私が一般的に「タイプ」エンティティで扱うものです。たとえば、あなたは車を持っています。フェラーリは車の一種です。そこから生まれる 2 つのエンティティは、Car と CarType です。

あなたが話している方法では、新しいタイプが導入されるたびに新しいエンティティを追加する必要があります。あなたが取得しようとしているのが車の「ニックネーム」だけである場合、それは別のエンティティではなく、単なる別のデータだと思います。異なるデータ (つまり、異なるプロパティ名) および/または異なるタイプの Car エンティティの動作の違いがない限り、このアプローチではあまりメリットがありません。リスクを軽減するために、FindCarByType() のようなリポジトリ メソッドを使用して、1 つのタイプのエンティティを処理することをお勧めします。

私は決して DDD の専門家ではなく、いくつかの概念に苦労しています (または、いくつかの概念の複数の解釈に苦労しているようなものです)。100% 純粋な実装はなく、私が見た各実装にはニュアンスがあることがわかりました。

フォローを編集

あなたが書いたものの一部を読み違えていたようです。ニックネームはすべての車ではなく、フェラーリの車だけです。答えは本当に「場合による」と思います。モデルの残りの部分にどの程度の専門分野がありますか? ニックネームを持つことはフェラーリのエンティティの間で一般的かもしれませんが、それは独占的なものですか? 実際のデータだけでなく、要件も重要です。基本的には、これらのエンティティにどれだけの専門性を期待しているかにかかっています。

于 2009-08-29T19:52:30.207 に答える