貧血ドメインモデルは、明らかにオブジェクト指向の原則などに反するため、 Evans and Fowler によってずっと以前に批判されていました。DDDコミュニティは、この発言と明らかに一致しています。
しかし、近年、これはアンチパターンではなく、SOLIDの原則に従う例であると主張しています。
私は長年、Spring Frameworkを使用して作業してきました。すべての会社のすべてのプロジェクトには、貧血モデル(JPAエンティティ)で動作するリポジトリを使用して、ビジネスロジックを含むサービスレイヤーが常にあります。さらに、ほとんどのサンプルは、Springの公式のサンプルであっても、この作業方法を示しています。
私の質問は、貧血ドメインモデルは依然としてアンチパターンと見なされているのですか?私たちは皆、(DDDに関して)間違ったことをしていましたか?リッチドメインモデルを使用することは、SOLIDの原則に違反していると思いませんか。
ADMは、マイクロサービスなどの分散サービスのソリューションに適したパターンです。今日のWebベースのビジネスケースの多くに適合します。
Order Domainオブジェクトがあるかどうかを検討します。 OOPアプローチでは、Order.Purchase()Order.Cancel()などを追加します。これは、メモリに注文を保持し、同じことに対して複数のことを行うデスクトップアプリでうまく機能します。インスタンス。
しかし、1つのこと、つまり注文のリストにアクセスして順番に購入するプログラム、または注文のリストを取得して順番にキャンセルするプログラムを備えた分散システムがある場合、同じオブジェクトに両方のメソッドがあると、センス。 2つのドメインまたはバインドされたコンテキストが必要です。
PurchaseSystemOrder.Purchase()
そして
CancelSystemOrder.Cancel();
これらのオブジェクトが共有する唯一のものは、プロパティのデータ構造です。
マイクロサービスをどんどん追加していくと、何十種類もの注文ができてしまいます。これらすべてのシステムで処理されている同じ概念的な順序であっても、ドメインオブジェクトとしてのan Orderについて話すことはもはや意味がありません。
データだけをカプセル化し、それに応じてサービスの名前を変更する、貧血モデルであるOrderを使用する方がはるかに理にかなっています。
PurchaseService.Purchase(Order order)
今度はOrderについてもう一度話し、現在デプロイされている他のサービスに影響を与えることなく、処理するために考えている新しいサービスを追加できます。
FowlerとCoはモノリスシステムのバックグラウンドに由来します。彼らの世界では、ADMアプローチは、これらの個別のサービスすべてがメモリ内でインスタンス化され、OrderDTOが渡されて変更される単一のアプリを意味します。これは、メソッドをリッチなOrderモデルに配置するよりもはるかに悪いでしょう。
しかし、分散システムには多くのプログラムがあり、それぞれが単一のOrderメソッドを必要とし、それを複数のオーダーで実行し、それぞれをロードし、メソッドを実行してから破棄します。必要なのは、単一のサービスとデータオブジェクトのストリームだけです。
すべてのメソッドの要件と依存関係を心配して1つのメソッドを呼び出し、その後すぐにオブジェクトを破棄することで、リッチモデルを完全に生成しても意味がありません。
さらに、メソッドの1つを変更すると、すべての分散コンポーネントを更新する必要があります。これらのコンポーネントはすべて、ロジックがリッチモデルに依存しているためです。
コードベースに必要のないもののためのスペースがない
SOLIDとDDDは互いに直交しているため、実際には互いに異なる方向に進んでいます。同じコードベースに共存でき、おそらく共存できるはずなので、一方が他方の除外に慣れていると言ってはいけません。
貧血ドメインモデルがアンチパターンになるのは、問題のあるドメインに多くの動作があり、サービスレイヤーメソッドが他のサービスレイヤーメソッドを呼び出して何かを実行しなければならない、コピー貼り付けされたロジックや依存関係が多数ある数百のサービスメソッドがある場合のみです。
DDDは制限付きコンテキストの概念により、マイクロサービスの優れたパラダイムです。
インフラストラクチャコードをドメインの一部として見る誘惑に注意してください。インフラストラクチャコードは、自分で記述していないもの、またはサードパーティのシステムとやり取りするフレームワークまたはライブラリに結合されているものです。データベース接続、SMTPメーラー、ORMライブラリ、アプリケーションサーバーランタイムなど、すべてがインフラストラクチャであり、回避できる場合は、それをドメインに含めたり、依存したりしないでください。
SOLIDの原則は、一連の汎用的な目的ですOOPコードを改善するために使用できるOOPコード。これらを使用して、優れたDDDコードベースを作成できます。
リッチドメインは、うまくできていればニースです。ないときの悪夢。貧血ドメインは常に悪いです。しかし、それはおなじみの快適な種類の悪いものです。
貧血ドメインだけで十分な場合は、汎用言語を選択するときに間違った言語を選択します。第4世代の言語は、特定の用途に特化しています。貧血が十分にあれば、それらを使用することであなたの生活が楽になったでしょう。
多くのフレームワークは、そのジョブをJavaジョブとしてもう宣伝することができなくなるまで、言語スペースに侵入します。これは、Java/Springジョブです。それらは、汎用言語を第4世代言語の粗野な形に変えます。
それはベストプラクティスですか、それともアンチパターンですか?まああなたは上司はほとんどの場合、コードベースで作業するために人々を雇うことができるかどうかを気にしています。ですから、私たちが汎用言語を使って人を雇っているふりをする必要がある場合は、そうします。
それで大丈夫なら、それで結構です。確かにあなただけではありません。
しかし、そうであるべきだと私に言わないでください。それ以上に私のために何かをしていると言わないでください。私はそれなしで生きる方法を知っています。私はそれを押し出す方法を知っているので、それに依存するものはほんの少しです。戦うのが難しいからといって、私に譲ってすべてを引き継がせるように頼んでいるなら、そうだと思う。
私のコードベースには、必要のないもののためのスペースがありません。
SOLIDと他の設計原則に関しては、貧血の領域でもそれらに大部分従うことができます。それらに従わないと、別の種類の問題が発生します。