貧血ドメインモデル:長所/短所


回答:


39

長所:

  • それがドメインモデルであると主張し、開発者の友人に自慢して、履歴書に載せることができます。
  • データベーステーブルから自動的に生成するのは簡単です。
  • 驚くほどうまくデータ転送オブジェクトにマッピングされます。

短所:

  • ドメインロジックは別の場所、おそらくクラス(静的)メソッドでいっぱいのクラスに存在します。またはGUIコード。または、複数の場所で、すべてロジックが競合しています。
  • これはアンチパターンなので、他の開発者は、オブジェクト指向設計の概念を理解しているかどうかを尋ねます。

7
+1データベーステーブルからコードを生成することについてのポイントは、一部の人々にとって非常に重要です。ラピッドプロトタイピングの開発モードにいる場合は、自動コード生成が非常に役立ちます。これが適切なオブジェクト指向設計であるとは思わず、物事を雑然とまとめると「技術的負債」が発生します。それにもかかわらず、多くのプロジェクトでは、市場投入までの時間がより優先されます。
ビルカーウィン

62
いいえ。貧血モデルがアンチパターンであるかどうかは意見の問題です。ファウラー(私が尊敬し、通常従う仕事)はそうだと言います。私は同意しません(私の言葉に重みがあるわけではありません)。また、オブジェクト指向のトレンチの多くも同意しません。純粋なOOモデリングは、業界全体が経験から知っているすべての場合に一般的に適用できるわけではありません。さらに、貧血モデルは、オブジェクト指向モデリングのガイドラインに従うことができます。したがって、適用される特定のケースを見ても、オブジェクト指向設計の理解に疑問はありません。
luis.espinal 2011年

12
パターンがアンチパターンであるかどうかは意見の問題です。堅牢なドメインモデルは優れたオブジェクト指向設計であり、貧血のドメインモデルは悪いオブジェクト指向設計です。したがって、OOのコンテキストでは、これはアンチパターンです。それは、すべての場合に使用されない、または不適切であるという意味ではありませんが、個人的な経験から、シングルトン中毒よりも悪いと思います。
テリーウィルコックス

7
関数型プログラミングの傾向があり、ドメインモデルには多くの副作用があると思います。ビジネスロジックがデータの入力を期待し、処理されたデータを返す、より機能的なスタイルのプログラミングが可能になるため、貧血のドメインモデルが復活しているように感じています。サービス層は、どのデータをどのビジネスロジック方式で処理する必要があるかを知ることにより、すべてのフローを監視します。
Didier A.

2
@TerryWilcoxええと、私は関数型の専門家ではありませんが、関数型プログラミングにもデータ構造があります。貧血のドメインモデルは、オブジェクトをデータのコンテナと同じように使用します。それらは構造体に似ています。私のポイントは、ADMを使用すると、時間の経過とともに新しい状態に変換される不変のデータを使用できる、より機能的な方法に移行できるということです。たとえば、これがScalaで行われていることがわかります。たとえば、OOPを少し活用して、それにFPを適用しようとしています。彼らがここでそれを説明するのと少し似ています:slideshare.net/debasishg/qconny-12
Didier A.

131

「貧血ドメインモデル」がアンチパターンであるのに、なぜこれを実装するシステムがこれほど多いのでしょうか。

いくつかの理由があると思います

1.システムの複雑さ

単純なシステム(インターネット上にあるほとんどすべての例とサンプルコード)で、実装したい場合:

注文への製品の追加

この機能を注文しました

public void Order.AddOrderLine(Product product)
{
    OrderLines.Add(new OrderLine(product));
}

素晴らしく、スーパーオブジェクト指向。

ここで、製品が在庫に存在することを検証し、存在しない場合は例外をスローする必要があることを確認する必要があるとしましょう。

注文を在庫に依存させたくないので、実際にはもう注文できません。サービスを開始する必要があります。

public void OrderService.AddOrderLine(Order order, Product product)
{
    if (!InventoryService.Has(product)
       throw new AddProductException

    order.AddOrderLine(product);
}

IInventoryServiceをOrder.AddOrderLineに渡すこともできます。これは別のオプションですが、それでもOrderはInventoryServiceに依存します。

Order.AddOrderLineにはまだいくつかの機能がありますが、通常はOrderスコープに制限されていますが、私の経験では、Orderスコープ外のビジネスロジックがはるかに多くあります。

システムが単なる基本的なCRUD以上のものである場合、ロジックの大部分はOrderServiceにあり、Orderにはほとんどありません。

2.開発者のOOPに対する見方

どのロジックがエンティティに適用されるべきかについて、インターネット上で多くの白熱した議論があります。

何かのようなもの

Order.Save

Orderは自分自身を保存する方法を知っている必要がありますか?そのためのリポジトリがあるとしましょう。

Orderは注文明細を追加できますか?簡単な英語で理解しようとしても、あまり意味がありません。ユーザーが商品を注文に追加するので、User.AddOrderLineToOrder()を実行する必要がありますか?それはやり過ぎのようです。

OrderService.AddOrderLine()はどうですか。今ではちょっと意味があります!

OOPについての私の理解は、カプセル化のために、関数がクラスの内部状態にアクセスする必要があるクラスに関数を配置するということです。Order.OrderLinesコレクションにアクセスする必要がある場合は、Order.AddOrderLine()をOrderに配置します。このようにして、クラスの内部状態が公開されることはありません。

3.IoCコンテナ

IoCコンテナを使用するシステムは、通常、完全に貧血です。

これは、インターフェイスを持つサービス/リポジトリをテストできますが、それらすべてにインターフェイスを配置しない限り、ドメインオブジェクトを(簡単に)テストできないためです。

「IoC」は現在、すべてのプログラミング問題の解決策として賞賛されているため、多くの人が盲目的にそれに従い、このようにして貧血ドメインモデルになってしまいます。

4. OOPは難しく、手順は簡単です

私はこれについて少し「知識の呪い」を持っていますが、DTOとサービスを持っている新しい開発者にとってはリッチドメインよりもはるかに簡単であることがわかりました。

おそらく、リッチドメインでは、ロジックを配置するクラスを知ることがより難しいためです。新しいクラスをいつ作成するのですか?どのパターンを使用しますか?等..

ステートレスサービスでは、最も近い名前のサービスでそれを叩くだけです。


どれだけ複雑になるかによると思います。1. 1-2の依存関係のように単純な場合、Orderクラスに保持します。2.中程度の複雑さの場合-OrderLinesクラスを作成し、Order.OrderLinesを使用してOrder <-> OrderLines通信と関連する依存関係を処理します。3.ただし、複雑さが高い場合は、アプリケーションサービスOrderServiceを使用して、OrderモジュールのスコープロジックをOrderに保持しながら、ほとんどの外部依存関係を許可します。
Eric P

13
すばらしい要約-これらすべての理由が、アンチパターンではない理由です。OOへのスラブの献身はアンチパターンです。次に、プロジェクションなしで並行性を追加し、ファウラースタイルのOOでどのように結び目を作るかを見てください。大規模な同時実行を行っている企業(グーグルなど)を見て、彼らが行っているOOの量を確認します。
DanH 2013年

うまく言った。Grailsを使用すると、3°が貧血につながるかどうかはわかりません。実際、1°に関しては、重要なアプリケーションのサービスレイヤーでロジックの移動を終了します。しかし、私はまだGrailsを使用したドメイン中心のアプローチを採用しています。ドメインはロジックに適した場所ですが、必要に応じてビットを1つ上に移動するため、実際にはそれほど良くありません。
youri 2013年

4
IoCと貧血の相関関係が見当たりません。まったく関係のない問題のようです。サービス/リポジトリまたはドメインオブジェクトがインターフェイスを実装するかどうかは、それらのテストとは関係ありません。むしろ、サービス/リポジトリ/ドメインオブジェクトをテストし、それら自体がインターフェイスを実装する依存関係からそれらを切り離します。そして、あなたがこれを正しく行うかどうかは、私が見ることができるIoCとは何の相関関係もありません。

2
私がGrokに苦労しているDDDについてのことは、あなたの最初のポイントです。「システムが単なる基本的なCRUD以上のものである場合、uはOrderServiceのロジックのほとんどを使用し、Orderはほとんど使用しません。」それは私には理にかなっていますが、それよりも複雑なシステムにDDDを使用する目的はありませんか?
ダン・リン

20

これに続いて、私の頭の中で非常に長い間考えがありました。「OOP」という用語は、本来意図されていない意味を持っていると私は信じています。よく知られているように、アナグラムは「オブジェクト指向プログラミング」を意味します。もちろん、焦点は「指向」という言葉にあります。「オブジェクト必須プログラミング」を意味する「OMP」ではありません。ADMとRDMはどちらもOOPの例です。それらは、オブジェクト、プロパティ、メソッドインターフェイスなどを利用します。ただし、ADMとRDMには、カプセル化の選択方法に違いがあります。それらは2つの異なるものです。ADMが悪いと言うことはOOPは正確なステートメントではありません。代わりに、さまざまなレベルのカプセル化に対して異なる用語が必要になるかもしれません。さらに、アンチパターンという用語は好きではありませんでした。これは通常、反対のグループのメンバーによって何かに割り当てられます。ADMとRDMはどちらも有効なパターンであり、単純に異なる目標を念頭に置いており、異なるビジネスニーズを解決することを目的としています。DDDを実践している私たちの人々は、少なくともこれを高く評価し、ADMの実装を選択した人々を非難することによって他のレベルに落ちてはなりません。ただ私の考え。


16

「これはアンチパターンなので、他の開発者は、オブジェクト指向設計の概念を理解しているかどうかを尋ねます。」

「貧血ドメインモデルはアンチパターンです。アンチパターンには長所がありません。」

貧血ドメインモデルがアンチパターンであるかどうかは意見の問題です。マーティン・ファウラーはそうだと言います、OOを裏返しに知っている多くの開発者はそうではないと言います。意見を事実として述べることはめったに役に立ちません。

たとえそれがアンチパターンであると広く受け入れられていたとしても、それでも(比較的少ないとはいえ)いくらか上向きになる可能性があります。


2
...どちらですか?私はあなたや誰かをだまそうとはしていませんが、私はプロについて本当に興味があります。短所は何千回も言及されていますが、私はまだADMの回復力のある長所を探しています(論争のフレーズは別として)。
struppi 2009

6
...これは、悪魔のアドボケイトをほとんど見せずにプレイしようとしている人のようです。the chances are it would still have some (though relatively little) upside.それなら名前を付けてください!仮説を立てる代わりに、少なくとも1つ!
そり2011年

2
シングルクラスに関連しないもの(実際のビジネス)のロジックがどこに属するかを知るのは簡単です。他の場所で述べたように、「リッチドメインモデル」は、複数の場所(サービスレイヤー、オブジェクトグラフに含まれる複数のクラスなど)にロジックを持つことになります。また、RDMでは、ビジネスロジック全体を簡単に表示したり、サイクルを回避したりすることは容易ではありません。ロジックのないダムデータ構造は、OOアプリケーションに配置されます。
ymajoros 2013年

1
私はこの記事はADMがアンチパターンではないと言うのは良いの引数与え見つけるblog.inf.ed.ac.uk/sapm/2014/02/04/...
syclee

1
アンチパターンは常に問題を引き起こし、パターンを使用して、何か問題を感じることなく、高品質のソリューションを備えたいくつかのやや大きなアプリケーション(10人の開発者の2〜3年の開発> 300KLOC)を出荷することに成功しました。使用しながら優れたコードを作成できます。
Ignacio Soler Garcia

13

ファウラーの主な異議は、次の意味で、ADMはオブジェクト指向ではないということだと私には思えます。他のコードによって操作されるパッシブデータ構造を中心に「ゼロから」システムを設計する場合、これは確かにオブジェクト指向設計というよりも手続き型設計のような匂いがします。

この種のデザインを生み出すことができる力が少なくとも2つあることをお勧めします。

  1. 新しいシステムを作成するために、オブジェクト指向環境で作業する必要があるとまだ手続き上必要であると考えている(またはできると想定している)設計者/プログラマー、および

  2. (言語に関係なく)OO以外の方法で設計されたレガシーシステムにサービスのような「顔」を配置するために作業している開発者。

たとえば、既存のCOBOLメインフレームアプリケーションの機能を公開するための一連のサービスを構築している場合、内部COBOLデータ構造を反映しない概念モデルの観点からサービスとインターフェイスを定義できます。ただし、サービスが新しいモデルをレガシーデータにマッピングして、既存の非表示の実装を使用する場合、新しいモデルは、ファウラーの記事の意味で「貧血」である可能性があります。たとえば、TransferObjectスタイルの定義のセットです。そして実際の行動のない関係。

この種の妥協は、理想的に純粋なOOシステムが既存の非OO環境と相互作用しなければならない境界で非常によくあることです。


8

チームがリッチドメインモデル(RDM)を構築し、それを長期間維持することができない、または望まない場合は、貧血ドメインモデル(ADM)が適しています。RDMで勝つには、システムで使用される主要な抽象化に注意を払う必要があります。どの開発グループでも、そのメンバーの半分以下、おそらく10分の1だけが抽象化に対応していることを理解してください。この幹部(おそらく1人の開発者のみ)がグループ全体の活動に対する影響力を維持できない限り、RDMはエントロピーに屈します。

そして、エントロピーRDMは、特定の方法で痛いです。その開発者は厳しい教訓を学びます。彼らには生きる歴史がないので、最初は彼らは彼らの利害関係者の期待に応えることができるでしょう。しかし、彼らのシステムがより複雑になると(複雑ではない)、それはもろくなるでしょう。開発者はコードを再利用しようとしますが、新しいバグを引き起こしたり、開発を後戻りしたりする傾向があります(したがって、見積もりを超過します)。

対照的に、ADM開発者は、新しい機能のために多くのコードを再利用することを期待しないため、自分自身に対する期待を低く設定します。時間が経つにつれて、彼らは多くの矛盾のあるシステムを持つでしょうが、それはおそらく予期せず壊れることはないでしょう。RDMが成功した場合よりも市場投入までの時間が長くなりますが、利害関係者がこの可能性を認識している可能性はほとんどありません。


5

「(言語に関係なく)非OO方式で設計されたレガシーシステムにサービスのような「顔」を置くために取り組んでいる開発者。」

多くのLOBアプリケーションについて考える場合、これらのレガシーシステムは多くの場合、同じドメインモデルを使用しません。アネミックドメインモデルは、サービスクラスでビジネスロジックを使用してこれを解決します。このすべてのインターフェイスコードをモデル内に配置することもできますが(従来のOOの意味で)、通常はモジュール性が失われます。


1
ビンゴ。これは多くの人がボートを逃しているように見える場所です。ADMには目的があります。それらの誤用はアンチパターンですが、それ自体はそうではありません。
luis.espinal 2011年

4

貧血ドメインモデルの記事に最初に出くわしたとき、私は「聖なるs ***、それが私がしていることです。ホラー!」と思いました。私は忍耐強く、Eric Evanの本への参照に従い、良い例であると考え、ソースをダウンロードしました。「貧血ドメインモデルを使用しない」とは、「サービスクラスを使用しない、メディエーターを使用しない、戦略を使用しない」、または「操作対象のクラスにロジックを配置する」という意味ではないことがわかります。

DDDの例には、サービスクラス、XyzUpdaters、シングルトン、およびIoCがあります。

私は貧血ドメインモデルが正確に何であるかについて混乱したままです。「見ればわかる」と期待しています。今のところ、私は良いデザインの前向きな例に満足しています。


1
その後、Eric Evanの本を購入しましたが、強くお勧めします。それは貧血ドメインモデルの反対の確かな例を提供します。
jamie 2012年

4

ADMを備えた「成熟した」システムで作業したことで、少なくとも、この質問に対していくつかの逸話的なフィードバックを提供できると感じました。

1)カプセル化の欠如

ADMを備えたライブシステムでは、たとえば 'obj.x = 100;と書く可能性があります。obj.save '、これがビジネスロジックに違反している場合でも。これにより、不変条件がオブジェクトでモデル化された場合には発生しない多くのバグが発生します。これらのバグの重大性と蔓延性が、ADMにとって最も深刻なネガティブであると私は感じています。

ここで、これが機能ソリューションであり、ADMの手順ソリューションが大幅に異なり、他の人がADMと機能ソリューションの表面の類似性に引き付けた可能性のある類似点は偶発的であることをここで指摘することが重要だと思います。

2)コードの膨張

ADMで生成されるコードの量は、OOP / RDMソリューションが作成するコードの5〜10倍であると推定しています。これは、おそらく50%がコードの繰り返し、30%が定型コード、20%がRDMの欠如から生じる問題の解決または解決によって説明されます。

3)ドメインの問題に対する理解が不十分

ADMとドメインの問題に対する理解の欠如は、いくぶん密接に関連しています。ナイーブなソリューションが発生し、既存のDMで要件をサポートすることが難しいため、要件は十分に考慮されていません。また、開発期間が長く柔軟性がないため、ADMはビジネスイノベーションの大きな障壁になります。

4)メンテナンスの難しさ

ドメインの概念が単なるコピーアンドペーストの再実装ではない可能性があることを考えると、ドメインの概念が表現されるすべての場所で変更されるようにするには、ある程度の厳密さが必要です。これにより、同じバグが何度も調査および修正されることがよくあります。

5)オンボーディングの難易度の増加

RDMの利点の1つは、ドメインのより迅速な理解を可能にする概念のまとまりであると思います。ADMを使用すると、概念が断片化されて明確性が失われる可能性があるため、新しい開発者が習得するのが難しくなります。

また、ADMの運用サポートコストをRDMのコストよりも高くしたいと思いましたが、これはいくつかの要因によって異なります。

他の人が指摘しているように、RDMの利点については、DDD(Greg Evans、Vince Vaughn、およびScott Millett)を参照してください。


1
グレッグ・エバンスはグレッグ・ヤングとエリック・エバンスの秘密の子供ですか?私はヴィンス・ヴォーンは、いずれかのDDDの本を書いていたことを知りませんでしたが、多分ヴォーンバーノンはあまりにも演技を始めた:)
knittl

ああ、私が上記を書いたときの私の記憶はやや混乱していたようです。それを指摘してくれてありがとう:)
モーフ氏

2

これは、ほとんどのアンチパターンと同じプロです。多くの人を長時間忙しくさせることができます。マネージャーはより多くの人を管理するほど報酬が高くなる傾向があるため、改善しないという強いインセンティブがあります。


7
その場合は言い換えさせていただきます。^^^一般的な命題を推測するために使用される純粋な事例証拠。
luis.espinal 2011年

十分な事例証拠が見つかったら、パターンを導き出すことができるかもしれません。そして、このパターンはよく知られており、変更管理に関する文献で適切に説明されています。
Stephan Eggermont 2011

4
「そして、このパターンはよく知られており、変更管理に関する文献で適切に説明されています。」-引用してください。さらに重要なことに、相関関係は因果関係を意味するものではありません。つまり、インプレースのアンチパターン(具体的にはソフトウェアパターン、要点は貧血ドメインモデル)のために人々が官僚形式主義で車輪を回しているのを見たからといって、前者を正当化するために後者が存在することを意味するわけではありません。あなたがたった今トランペットしたもの。修辞的なスローガンは、複雑な問題を説明するための似顔絵ではありません。繰り返しますが、相関関係は因果関係を意味するものではありません。
luis.espinal 2011

4
Gerald M. WeinbergによるQualitySoftware Management、特に第4巻を読むことをお勧めします。そして、私は、その発生ではなく、継続的な存在の考えられる原因のみを主張します。ピーターの法則は適切な代替案を提供します。
Stephan Eggermont 2011

ありがとう、機会があれば読みます(引用を提供するための+1)。その本はそれをよく知られているアンチパターンとして提示していますか?それに加えて、それは相関関係だけでなく因果関係も主張/示していますか?あなたは今それを「可能な」説明として主張します。あなたの元のテキストはそれを確実に、詳細よりもレトリックで表現しています(それが私がそれを「純粋な憶測」と呼んだ理由です)。あなたの意図されたかどうか、その後、または知っているだけで社説事故、そして私はそれを読んだ時のテキスト内に存在するものから、推測することができます。
luis.espinal 2011

2

Eric Pの回答と上記の他のいくつかの回答に沿って、ADMの主な欠点は、OODが失われること、特にドメインコンセプトのロジックとデータをまとめて、実装の詳細が隠されていることです。 APIは豊富な場合があります。

エリックはさらに、注文にアイテムを追加する前に在庫をチェックするなど、ドメインクラスを操作するロジックに必要な情報がドメインクラスの外部にあることが多いことを指摘します。ただし、その答えがこの包括的なロジックを保持するサービスレイヤーなのか、それともオブジェクト設計の一部として処理する方が適切なのかは疑問です。 誰かがInventoryオブジェクト、Productオブジェクト、およびOrde​​rオブジェクトについて知っている必要があります。おそらく、それは単にOrderSystemオブジェクトであり、Inventoryメンバー、Ordersのリストなどがあります。これはサービスとそれほど変わらないように見えますが、概念的にはより一貫性があると思います。

または、次のように見てください。内部クレジット残高を持つユーザーがいる可能性があり、User.addItemToOrder(item)が呼び出されるたびに、アイテムの価格を取得し、追加する前にクレジットをチェックします。これは妥当なOOのようです。設計。これをService.addItemToUserOrder(user、item)に置き換えることで何が失われるのか正確にはわかりませんが、何が得られるのかもわかりません。損失は​​、コードの余分な層に加えて、より不格好な書き方と、基礎となるドメインモデルの強制的な無知であると思います。


1

システムの複雑さとバリエーションの粒度が大きくなるにつれて、適切に設計されたメッセージパッシングオブジェクトモデルによって提供されるインターフェイスポイントのカプセル化と統合により、広範囲にわたるリファクタリングなしで重要なコードを変更および維持することがはるかに安全になることに注意してください。

ADMによって作成されたサービスレイヤーは、確かに実装が簡単ですが(比較的考えが少なく、分散型のインターフェイスポイントが多いため)、稼働中の成長中のシステムを変更するときに問題が発生する可能性があります。

また、すべてのケースでドメインモデルが必要なわけではないことも付け加えておきます(ADMモデルは言うまでもありません)。データ駆動型であり、アプリケーション全体のロジック/ビジネスルールに依存しない、より手続き型/機能的なスタイルのタスクを使用する方がよい場合があります。

アプリ全体の長所と短所を決定しようとしている場合は、コードを1行書き始める前に、特定のアプリケーションでそれぞれがどのように見えるかを最初に設計することが重要だと思います。両方のスタイルでアプリケーションをCRCまたはワイヤーフレーム化したら、一歩下がって、どちらがより理にかなっており、アプリケーションにより適しているかを判断します。

また、どちらを維持するのが簡単になるかを前もって考えてください...


1

それはより良い予測可能性を与えます。特にプロジェクトに時間と材料が支払われる場合、そのようなマネージャー。すべての変更は多くの作業を意味するため、困難な作業は多くの反復作業の背後に隠れることがあります。適切に設計されたDRYシステムでは、常に新しいことをしているため、予測可能性は非常に悪くなります。


1

ドメイン駆動設計に関するEricEvansの本を最初に読んだ後、それが優れたドメインモデルクラスを設計するための単なる戦術パターンの集まりではないことを本当に理解していませんでした。

トピックについてさらに学び、戦略的パターンも使用した後、私はようやく、最初解決しようとしているビジネス上の問題深く理解することがすべてであると理解し始めました。

その後、集約、エンティティなどの戦術パターンを適用するためにシステムのどの部分が適合するかを決定できます。貧血モデルではなく)いわゆるリッチドメインモデルとともに、、リポジトリます。しかし、これらのパターンから利益を得るには、システムのその部分のビジネスロジックに関して十分な複雑さ必要です。

したがって、目前の問題の解決策を実装する場合は、最初に、この特定の問題にCRUDベースのアプローチを使用するか、前述の戦術パターンとともにリッチドメインモデルに投資する方がよいかどうかを判断する必要があります。

CRUDの方が理にかなっている場合、たとえば、複雑なビジネスロジックがなく、ロジックのほとんどがドメインモデルを実装するデータの変換、転送、永続化に関係している場合、不必要なやり過ぎになる可能性があります。これは、実行する作業がそれほど多くないことを意味するのではなく、単に、最も多くの実装作業を生み出すのはビジネスルールではありません。しかし、この場合、そのようなものはありませんドメインモデルがまったくないという理由だけで貧血ドメインモデルはありません。むしろ表示されるのは、DTO(データ転送オブジェクト)やDAOなどです。(データアクセスオブジェクト)およびデータを操作するサービスクラス。また、対応する操作は、データをある表現から別の表現に変換し、ビジネスロジックをほとんどまたはほとんど使用せずにデータを移動することに大きく関係しています。

あると判断した場合 ドメインモデルに投資するよりも時間の経過とともに変化する複雑なビジネスロジックたくさん私の経験からすると良い考えです。その理由は、コードを介してビジネスパースペクティブを表現しやすくなり、ビジネスドメインとそのルールを反映する対応する操作を理解しやすくなるためです。これは、すべてのユースケースにドメインモデルクラスが存在する必要があるという意味ではありません。たとえば、変更および永続化する状態がない場合、純粋関数のように実装されるドメインロジックを含むドメインサービスのみが存在する可能性もあります。

ただし、ビジネスドメインで目的と意味を持つ、変更および永続化する状態もある場合は、状態とこの状態を変更する動作をカプセル化する必要があります。それでは、誰も簡単にビジネスルールを回避することができず、それによって重大な失敗とともに無効な状態につながります。いわゆる貧血ドメインモデルは、しばしばそのような問題の原因です。これは、さまざまなコンポーネントが同じ「貧血」ドメインモデルクラスで動作し、そのビジネスエンティティの全体的な不変条件を気にせず、知らずに、状態の一部をチェックして状態の一部を変更するコードを見る場合によくあります。これをアンチパターンと呼ぶ必要はありませんが、それを理解することが重要です。上記の問題に加えて、DDDベースのアプローチでリッチドメインモデルの多くの利点が失われます。動作とそのデータが同じクラスに配置されるドメインモデルを使用する場合、そのクラスの操作を呼び出すさまざまな「クライアント」が多数存在する可能性もありますが、ビジネスエンティティのビジネス不変条件が次のように順守されることを気にする必要はありません。ドメインモデルクラスは常にそれを処理し、無効な操作について「クライアント」に通知したり、セーフティネットとして例外をスローしたりすることもできます。

だから結論として、私はそれが重要だと思います貧血のドメインモデルクラスと(などのDTOまたはDAOをなど)のクラスのようなデータ構造混同しません。注意深く意図的に選択されたCRUDベースのアプローチでは、複雑なビジネスロジックが少なすぎるため、ドメインモデルを使用しようとする利点はありません。

よる貧血ドメインモデル私は、私はむしろ近いこれらのロジックが変更されたデータにする必要があります別のコンポーネントに分散され、複雑なビジネスロジックとビジネスルールがたくさんあることがわかります、そこからコードを参照することになります。

途中で私が学んだ別の教訓もあります。ステーキ所有者が日常業務で使用しているのと同じビジネス言語(ユビキタス言語とも呼ばれます)をコードで使用しようとすると、理解に関する多くの利点がすでに得られます。ビジネスドメインとコードの可読性の向上により、CRUDベースのアプローチとドメインモデルベースのアプローチのどちらを使用する場合でも、非常に役立ちます。


0

Michaelの答えを拡張するために、私はそのコードがどこに行くべきかが(かなり)明確であると思っていました:注文と在庫の間の相互作用を処理する専用のメディエーターに。

私のPOVから、ドメインに関する重要なことは、isInThisState()メソッドなどの単純なテスト動作を保持する必要があるということです 。私の経験では、これらはほとんどの企業のサービスの涙(原文のまま:))にも散在しており、コピーまたはコピーされたものは際限なく書き直されています。これらはすべて、標準の結束規則に違反します。

私の見解では、アプローチは、実用的である限り多くのビジネス行動を保持するDMを目指し、残りを明確に指定された領域に配置することです(つまり、サービスではありません)。


メディエーターについてのことは、とにかくそれと手続き型プログラミングの間にほとんど違いがないということです。どちらのオブジェクトにも属さないいくつかの関数をグループ化するだけです。それらを別のオブジェクトにグループ化しても、大きな違いはありません。
ロブ・グラント

0

私のチームは個人的にADMを好みます。ドメインの特定の部分を表す一連のビジネスオブジェクトがあります。これらのオブジェクトをデータベースに保存するためにサービスを使用します。私たちのビジネスオブジェクトにはメソッドがありますが、これらのメソッドはその内部状態を操作するだけです。

RDMよりもADMを使用することの利点は、オブジェクトをdbに永続化する方法に見ることができます。レガシーコードシステムで作業している開発者は、(新しいシステムからの)ビジネスオブジェクトを使用し、現在のデータアクセスレイヤーを引き続き使用して、これらのオブジェクトをデータベースに永続化できます。RDMを使用すると、レガシーシステムの開発者は、リポジトリオブジェクトをビジネスモデルに挿入する必要があります...これは、現在のデータアクセス層と一致しません。


-15

貧血のドメインモデルは、アンチパターンです。アンチパターンには長所がありません。


10
同意しません。ほとんどのアンチパターンには、他の選択肢よりも優れたソリューションであるコーナーケースがあります。
ビルカーウィン

19
アンチパターンには長所があります。それが、通常は悪い考えであるにもかかわらず、人々がそれらを使用する理由です。
クリストファージョンソン

6
何かが単なる意見である場合(たとえそれがファウラーの口径のものであっても)、事実としてその何かがアンチパターンであるとパロットすることは、有効な答えの形式ではありません。
luis.espinal 2011年

@luis:あなたのコメントを見る前に私が書き込もうとしていたこと。さらに、目的を果たすためのツールが存在します。ファウラーがそれをOOと呼びたくないのであれば、それは問題ありません。しかし、それは自動的に悪いソリューション/アーキテクチャなどを示すものではありません。
JensG 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.