「制御の反転」は「貧血領域モデル」を促進しますか?


32

前回のプロジェクトでIoC Containerを使用したとき、貧弱なエンティティとステートレスサービスでのビジネスロジックの大部分になりました。

「Inversion of Control」を利用する他の開発者によって書かれたプロジェクトを見てきましたが、それらは常に「Anemic」です。

「Anemic Domain Model」はアンチパターンであるため、IoCとRich Domainを使用できますか?彼らの良い例、それを行うオープンソースプロジェクトはありますか?


私たちはあなたを助けるためにあなたの特定のケースのいくつかの特定の例を見る必要があると思います。
Martijn Verburg

1
申し訳ありませんが、私はコードスニペットを意味しました:)
Martijn Verburg

回答:


11

まず、DIとIoC 同義語ではありません。申し訳ありませんが、私はそれを指摘しなければなりません(あなたは彼らがそうだと思うようです)。

お問い合わせは...依存性注入は単なるツールです。このツールの使用方法は完全に別のものです。問題を追加する可能性のある他のツール(設計パターン)もあります。たとえば、MVCパターンを広く採用することは、Anemic Domain Modelアンチパターンを形成するための重要な要素の1つであると感じています。 、それらを強制するだけでなく、DBエンティティを何か有用なものに変換します。一方、ビジネスレイヤーは、データベースエンティティに1対1でマッピングされる単純なORMである単純なデータアクセスレイヤーになります。

確かにアプリケーションの設計方法です。必要に応じて適切なドメインモデルを作成できます。これらすべてのIoC、DI、MVCによって停止することはありません。あなたを止めることができるのはあなたのチームです。あなたはどういうわけか彼らに正しい道を使うよう説得する必要があり、多くのソフトウェア開発者は強力なアーキテクチャの背景を持っていないので難しいかもしれません。


これに加えて、おそらく、Eric Evans et al。によって支持されているDDDアプローチをのぞいてみることができます。
Martijn Verburg

1
エリック・エヴァンスの本を読みました。一般的な方法論とユビキタス言語には適していますが、実際の例には多少欠けています。
Mag20

DIとIoCの違いを指摘してくれてありがとう。この問題は、IoCとDIに関係していると思います。それを反映するように質問を変更しました。
Mag20

DIフレームワーク/コンテナ(春DI、CDI、ユニティ)との私の経験では、彼らは確かにない私には、開発者が真(すなわち、ステートフル)オブジェクトを使用してから制約されるべきでないことを意味し、「正しいドメインモデル」を作成するからあなたを停止します。しかし、DIはそれを実際にはサポートしていません。
ロジェリオ

8

ほとんどの(すべてではないにしても)アプリケーションは、インフラストラクチャとドメインの懸念が混在しています。特定のレベルの複雑さに達すると、ドメインがインフラストラクチャから分離されている場合、管理が容易になり、推論が容易になり、独立して進化できるようになります。

もちろん、ドメインモデルはシステムの残りの部分と通信する必要があり、通常、インフラストラクチャの問題(データベースアクセスなど)が注入されたステートレスサービス(ドメインの一部)と通信します。IoCコンテナーを使用しても、この依存関係は削除されず、その構成が別の領域に移動されます。これも、推論と保守が容易になります。

エンティティは状態を保存しており、ビジネスルールを担当する必要があります。サービスがすべての不変条件およびその他のビジネスルールを実施している場合、ロジックが間違った場所にある可能性があります。

ロジックを適切な場所に配置したにもかかわらず、インフラストラクチャの単なるラッパーであるサービスや、単なるプロパティバッグであるエンティティに終わった場合、ドメインは正当化するほど複雑ではない可能性が非常に高い独自のモデルのオーバーヘッド。DDDについてお読みいただく内容には、複雑なドメインのみを対象とした免責事項が記載されていますが、これはあまりにも忘れられがちです。


7

ソースに移動します。貧血領域モデルに関するファウラーの作品から始めてください。彼は、優れた実践の例としてエリック・エヴァンのドメイン駆動設計を参照しています。そのためのソースコードはこちらです。ダウンロードしてください。

Inversion of Control(@Autowiredを検索)を使用し、サービスクラス(BookingService)と「ビジネスプロセス」クラス(ItineraryUpdaterなど)を持っていることを確認します。

ファウラーの元の記事は、あなたが探している例への道を開きます。


実際、このサンプルアプリは、本で説明されているDDDに準拠していません。本との特定の矛盾は、ドメイン固有のコードを含めることを許可することにより、「インフラストラクチャ」の概念に完全に違反するということです。たとえば、VoyageRepositoryHibernateインフラストラクチャ層に配置されたクラスは実際にはドメイン層に依存しています。
ロジェリオ

はい、本は、インフラストラクチャ層がドメイン層の「下」にあり、「サービスしているドメインの特別な知識を持ってはならない」と73ページで述べています。これは私には意味がありませんでした。VoyageRepositoryHibernateとVoyageRepositoryJDBCクラスの2つのVoyageRepository実装を持つプロジェクトを考えてみましょう。それらの実装は必然的に非常に異なり、技術に固有です。これらはドメイン層に属しますか?またはインフラストラクチャ層ですか?本によると、コードでは、逆方向に実行します。インフラストラクチャ層はドメイン層を参照できますが、逆はできません。
ジャミー

それらはドメイン層に属します、はい。JDBCベースの実装には、アプリケーションデータベースのテーブルと列に関連付けられた、ドメインに固有のSQLコードが含まれます。「インフラストラクチャコード」は技術的な問題を解決するためにのみ使用されるべきであり、(理想的には)異なるアプリケーションとドメイン間で完全に再利用可能であるべきであるため、インフラストラクチャレイヤーにドメインまたはアプリケーション固有のコードを配置するのは間違っています。ドメイン層に「低レベル」コード(SQLなど)を配置するためのソリューションは、完全に移動するのではなく、ORMなどのより優れたインフラストラクチャ上に実装することです。
ロジェリオ

私にとって、save(MyDomainObject foo)の実装は純粋に技術的な懸念事項です。YMMV。
ジャミー

階層化されたアーキテクチャの基本的なルールに違反しない場合のみ:下位層上位層に依存できません。したがって、save(foo)ドメインモデルが変更されたときに変更される可能性のあるコード(たとえば、新しい属性がに追加された場合)を実装した場合、MyDomainObject(定義により)ドメイン層に属している必要があります。そうしないと、「レイヤー」を持つことについて話すことができなくなります。
ロジェリオ

7

IoCとリッチドメインを使用できますか?彼らの良い例、それを行うオープンソースプロジェクトはありますか?

IoCの代わりにDIを意味すると仮定し、あなたが取り組んだプロジェクトはSpringのようなDIコンテナを使用しています。IoCには、DIとロケーターパターンという2つの主なフレーバーがあります。Locatorパターンが問題になる理由がわからないので、DIに注目しましょう。

私はそれが可能だとは思わない、または少なくとも非常に非現実的だろう。DIコンテナーの主な特徴は、オブジェクトを他のオブジェクト(「管理オブジェクト」)に注入するときにオブジェクトの作成を制御することです。プロジェクトの実行時に生存している管理対象オブジェクトのセットは、プロジェクトに存在するドメインアイテムから独立していますが、オブジェクトの配線方法とそれらに割り当てられるスコープ(シングルトン、プロトタイプ)に依存します。

これが、DIコンテナにドメインオブジェクトを管理させたくない理由です。ただし、オブジェクトを(新規で)手動で作成する場合、他のオブジェクトをドメインオブジェクトに挿入することはできません。(手動の配線を回避する潜在的な回避策を残します。)実装を他の実装に置き換えるためにこれらの注入が必要なため、DIを使用してリッチドメインオブジェクトの機能を置き換えることはできません。したがって、ドメインオブジェクトに機能を配置したくない、またはDIの機能を失うことになります。

オブジェクトを管理しない架空のDIコンテナーがどのように機能するかはわかりませんが、既存の実装ではそれが許可されていません。したがって、DIがオブジェクトの管理に依存していると主張するのは公平です。したがって、潜在的なリッチドメインオブジェクトを1つの貧弱なクラスと1つまたは複数のトランザクションスクリプトクラスに分割するように常に誘惑されます。


Rich Domain ModelとDependency Injectionの間の緊張に関しては、この答えは本当に頭を悩ませています。
ジャラハリ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.