web-dev-qa-db-ja.com

貧血ドメインモデルとドメインサービスインジェクション

貧血ドメインモデル は、Martin Fowlerによるドメイン駆動設計のアンチパターンとして説明されています。ドメインモデルでビジネスロジックを使用するには、多くの場合、ドメインサービスを使用します。ただし、ドメインサービスをドメインモデルに挿入することは、Vaughn Vernonによって有害で​​あると見なされています(「ドメイン駆動設計の実装」(387ページ)を参照)。

私の意見では、それらの意見は矛盾していますが、これは本当ですか?両方の点をどのように考慮することができますか?

それは本当にドメインサービスが注入されたリッチドメインモデル貧血ドメインモデルと通常のドメインサービス

19
Sjoerd222888

貧血モデルは単なるデータコンテナーです。動作は含まれていません。 (これは実際には機能的パラダイムで良いことと考えられるかもしれません。)貧血モデルの反対はnotモデルですドメインサービスの完全な注入。あなたは2つの極端なことを説明しています-どちらも悪いことです。

貧血モデルがある場合、OOPオファーを完全には受け入れていません。これらのモデルにサービスを注入し始めた場合、そこに属していない懸念を注入している可能性があります。またはあなたのモデルはあなたが思っているよりも貧血です。なぜ必要なものを提供しているのに欠けているサービス以外になぜあなたはサービスが必要なのですか?

両方の「テル」を回避すると、より強力な設計につながります。モデルに必要なサービスに何かありますか?多分それはモデルに移動する必要があります。そうでない場合は、おそらくあなたの懸念を再考する必要があります。モデルの動作はモデル内で機能します。それは主に(それだけではないにしても)メンバー自身に関係するべきです。ただし、onまたはwithで機能するものがまだありますモデル。たとえば、モデルは、何らかの形で関与している場合でも、TCP接続を開いたり、UIイベントをリッスンしたりすることはできません。それは、他の誰かの責任であり、誰かが決して属さないことですinsideモデル。

16
Scant Roger

それは矛盾していません。どちらの支持者も、実際のコードをドメインオブジェクト自体に配置することを望んでいます。

すなわち。

public class Order
{
    private string status = "not bought";
    public void Buy()
    {
        this.status = "bought";
    }
}

対ADM

public class Order
{
    public string Status = "not bought";
}

public class BuyingService
{
    public Order Buy(Order order)
    {
         Order o = new Order();
         o.status = "bought";
         return o;
    }
}

対注入されたサービス

public class Order
{
    public Order(IBuyingService bs)
    {
        _bs = bs;
    }
    private IbuyingService _bs;
    private string status = "not bought";
    public void Buy()
    {
        this.status = _bs.Buy();
    }
}

public class BuyingService : IBuyingService
{
    public string Buy()
    {
         return = "bought";
    }
}

率直に言って、各アプローチにはプラスとマイナスがあります。あなたが選ぶものは主に個人的な好みの問題です

7
Ewan