15

エンタープライズ アプリケーション アーキテクチャのパターンで、Martin Fowler は、ドメイン ロジックを編成するための 2 つのパターン、ドメイン モデルサービス層について説明しています。ドメイン モデル パターンは「純粋な OOP」アプローチであり、モデル (おそらく ORM を使用してデータベースから検索されるオブジェクト) にビジネス ロジックが含まれます (ただし、おそらく別のクラスのロジックに委譲するだけです)。

サンプル ドメイン モデル

サービス層パターンはドメイン モデル パターンに似ていますが、その前に実行可能なビジネス オペレーションを含む薄い層があります。MVC では、コントローラーは主にサービス層と対話します。適切に設計された MVC Web アプリケーションのほとんどは、このパターンを使用していると思います。

サンプル サービス層

さて、私の質問に。Martin は、ドメイン モデル アプローチはよりオブジェクト指向のアプローチであり、したがってより優れていると示唆しています。私の経験では、実際に実装するのは非常に困難です (不可能を参照)。

上の最初の図の例を見てください。2 つの「エンティティ」ContractとがありProductます。これらは、マッパーを使用してデータベースに永続化されます。例では、 がありRecognitionStrategyます。Martin は、実際のビジネス ロジックを含むこの戦略に委任するためのメソッドをエンティティ自体に配置します。contract.calculateRecognitionsクライアントは、またはを使用してこの計算を実行しますcontract.recognizedRevenue(someDate)。同様の設計を実装する場合、通常、クライアント インターフェイスをstrategy.calculateRecognitions(contract)およびとして記述しますstrategy.recognizedRevenue(contract, someDate)。これにより、戦略と契約を調整するためにサービス層が必要になります。使用される具体的な戦略がサービスに注入されます。

マーティンのアプローチは、デザインの観点からは間違いなく魅力的ですが、セットアップを回避する作業ははるかに困難です。

  1. a をインスタンス化するときに戦略を渡すのはProduct面倒です。使用する具体的なサービスでカリー化されたファクトリを介してを作成する必要がありますProduct。これにより、作成時にエンティティに渡されます。
  2. データベース アクセスに対するきめ細かい制御ができません。ORM の設定によっては、 へのContract委任がProductごとにクエリを実行する場合がありますProductProductマッパー (または ORM) に s を貪欲にロードすることは、 をロードするContractが を呼び出すつもりがない場合、熱心すぎるかもしれませんcontract.calculateRecognitions()。私のアプローチでは、サービスがデータベース抽象化レイヤーの知識を持っているため、よりきめ細かい制御が可能になりますが、エンティティはそうすべきではありません。

ここに列挙していない問題点が実際にはもっとあると確信しています。

Martin のアプローチには、純粋なデータ モデル パターンを使用するよう説得する具体的な利点は何ですか?

4

2 に答える 2

6

最初のポイントに関しては、製品オブジェクトをインスタンス化するときに依存性注入を使用する必要があります。オブジェクト グラフの構築は完全にフラグが立てられた責任であり、ビジネス ロジック (単一責任の原則) と混合しないでください。

2 番目の点については、ベンダーの特殊性はデータ アクセス レイヤーの背後に隠されている必要があり、DAO またはリポジトリはニーズに応じてオブジェクトを返す必要があります。

Product を貪欲にロードすることに対する懸念 (関係が 1 対多の場合) に対する別の方法は、 Product DAO を Contract オブジェクトに注入することです。そのアプローチを使用すると、必要に応じてコントラクトに関連する Product を取得できます (おそらく、内部でも使用できるゲッターで)。

もちろん、完全な解決策は存在せず、常にトレードオフが存在します。アーキテクトとしてのあなたの仕事は、アプリケーションにより適したアプローチを評価することです。

私の個人的な経験では、サービス クラスに依存しすぎると、責任が明確に定義されておらず、通常はテストが難しすぎる巨大なクラスが生成される傾向があることに気付きました。

したがって、ドメイン モデル アプローチを使用する利点は、懸念事項が明確に分離され、テスト容易性が向上することです。

最後に、「純粋な」ドメイン モデル アプローチを使用する必要はありません。ドメイン モデルとサービス レイヤーは併用されることが想定されています。ドメイン モデル エンティティは、その境界内にある動作をカバーし、サービス レイヤー カバー ロジックはどのドメイン エンティティにも属しません。

興味深いと思われる追加のリファレンス

Domain Driven Design and Development In Practice - DDD に関する興味深い記事

依存性注入、Spring と Guice を使用したデザイン パターン - 依存性注入に関する素晴らしい本

よろしく、

エマニュエル・ルイス・ラリゲ・ベルトラム

于 2015-04-23T00:11:43.037 に答える