88

ドメイン駆動型設計の詳細があまりないように思われる部分の 1 つは、ドメイン モデルをインターフェイスから分離する方法と理由です。私はこれが良い習慣であることを同僚に納得させようとしていますが、あまり進歩していないようです...

彼らは、プレゼンテーション層とインターフェイス層の好きな場所でドメイン エンティティを使用します。表示モデルまたは DTO を使用してドメイン層をインターフェイス層から分離する必要があると彼らに主張すると、彼らはそのようなことを行うことにビジネス上の価値がないと反論します。元のドメイン オブジェクトと同様に。

そのため、これを裏付けるために使用できる具体的な理由を探しています。具体的には:

  1. プレゼンテーション層でドメイン オブジェクトを使用してはいけないのはなぜですか?
    (答えが明らかな「デカップリング」である場合は、このコンテキストでこれが重要な理由を説明してください)
  2. インターフェイスからドメイン オブジェクトを分離するために、追加のオブジェクトまたは構造体を使用する必要がありますか?
4

14 に答える 14

51

簡単に言えば、その理由は実装とドリフトの 1 つです。はい、プレゼンテーション レイヤーは、ビジネス オブジェクトを適切に表現できるようにするために、それらについて知る必要があります。はい、最初は、2 種類のオブジェクトの実装に多くの重複があるように見えます。問題は、時間が経つにつれて、物事が両側に追加されることです。プレゼンテーションが変化し、プレゼンテーション レイヤーのニーズが進化して、ビジネス レイヤーから完全に独立したもの (色など) が含まれるようになります。その間、ドメイン オブジェクトは時間の経過とともに変化します。インターフェイスから適切に分離していないと、ビジネス オブジェクトに一見無害な変更を加えて、インターフェイス レイヤーを台無しにするリスクがあります。

個人的には、物事にアプローチする最善の方法は、厳密に強制されたインターフェイス パラダイムを使用することだと考えています。つまり、ビジネス オブジェクト層は、通信できる唯一の方法であるインターフェイスを公開します。インターフェイスに関する実装の詳細 (つまり、ドメイン オブジェクト) は公開されません。はい、これは、ドメイン オブジェクトを 2 つの場所に実装する必要があることを意味します。あなたのインターフェース層とあなたのBO層で。しかし、その再実装は、最初は余分な作業のように見えるかもしれませんが、将来のある時点で大量の作業を節約するデカップリングを実施するのに役立ちます.

于 2009-05-04T18:28:00.190 に答える
19

私はこれに苦労しました。プレゼンテーションで DTO を使用するのが理にかなっている場合があります。システムで会社のドロップダウンを表示したいとしましょう。値をバインドするために会社の ID が必要です。

サブスクリプションへの参照を含む可能性のある CompanyObject をロードする代わりに、名前と ID を含む DTO を送り返すことができます。これは良い使い方です。

では、別の例を見てみましょう。私は見積もりを表すオブジェクトを持っています。この見積もりは人件費、設備などで構成されている可能性があり、これらすべての項目を取得して合計するユーザーによって定義された多くの計算が含まれている可能性があります (各見積もりはタイプによって異なる場合があります)計算の)。このオブジェクトを 2 回モデリングする必要があるのはなぜですか? UI で計算を列挙して表示できないのはなぜですか?

通常、DTO を使用してドメイン層を UI から分離することはありません。私はそれらを使用して、自分のドメイン層を自分の制御の及ばない境界から分離しています。誰かがビジネス オブジェクトにナビゲーション情報を入れるという考えはばかげています。ビジネス オブジェクトを汚染しないでください。

誰かがビジネスオブジェクトに検証を入れるという考えは? まあ、これは良いことだと言います。UI だけがビジネス オブジェクトの検証を行うべきではありません。ビジネス層は独自の検証を行う必要があります

UI 生成コードを busienss オブジェクトに入れるのはなぜですか? 私の場合、UI とは別に UI コードを生成する別のオブジェクトがあります。私は自分のビジネス オブジェクトを Xml にレンダリングする個別のオブジェクトを持っています。この種の汚染を防ぐためにレイヤーを分離する必要があるという考えは、なぜビジネス オブジェクトに HTML 生成コードを入れるのでしょうか...

編集 もう少し考えてみると、UI 情報がドメイン層に属している場合があります。これはドメイン レイヤーと呼ばれるものを曇らせる可能性がありますが、私はマルチテナント アプリケーションに取り組みました。このアプリケーションは、UI のルック アンド フィールと機能ワークフローの両方で非常に異なる動作をしていました。さまざまな要因によって異なります。この場合、テナントとその構成を表すドメイン モデルがありました。それらの構成にはたまたま UI 情報が含まれていました (たとえば、一般的なフィールドのラベル)。

オブジェクトを永続化できるように設計する必要がある場合、オブジェクトも複製する必要がありますか? 新しいフィールドを追加する場合は、追加する場所が 2 つあることに注意してください。おそらくこれは、DDD を使用している場合、すべてのエンティティが永続化されたドメイン オブジェクトであるかという別の疑問を提起しますか? 私の例では、彼らがそうだったことを知っています。

于 2009-05-04T18:53:04.357 に答える
16

同意しません。

最善の方法は、プレゼンテーション層のドメインオブジェクトから始めて、他の方法で実行できるようになるまで続けることだと思います。

一般に信じられていることとは異なり、「ドメインオブジェクト」と「値オブジェクト」はプレゼンテーション層でうまく共存できます。そして、これがそれを行うための最良の方法です。ドメインオブジェクトとの重複(および定型コード)を減らし、両方の世界のメリットを享受できます。リクエスト間で値オブジェクトを使用するための調整と概念の簡素化。

于 2009-05-14T06:58:49.033 に答える
16

これは、ASP/JSP ページから SQL を除外するのと同じ理由で行います。

プレゼンテーションとドメイン層で使用するためにドメイン オブジェクトを 1 つだけ保持すると、その 1 つのオブジェクトはすぐにモノリシックになります。UI 検証コード、UI ナビゲーション コード、および UI 生成コードが含まれ始めます。次に、すぐにすべてのビジネス レイヤー メソッドをその上に追加します。これで、ビジネス レイヤーと UI がすべてごちゃ混ぜになり、それらすべてがドメイン エンティティ レイヤーでごちゃごちゃになっています。

その気の利いた UI ウィジェットを別のアプリで再利用したいですか? さて、この名前、これらの 2 つのスキーマ、およびこれらの 18 個のテーブルでデータベースを作成する必要があります。ビジネス検証を行うには、Hibernate と Spring (または選択したフレームワーク) も構成する必要があります。これらの 85 の他の無関係なクラスも含める必要があります。それらはたまたま同じファイルにあるビジネス層で参照されているからです。

于 2009-05-04T18:28:27.707 に答える
4

サーバーとUIで同じモデルを使用しています。そして、それは苦痛です。いつかリファクタリングする必要があります。

問題は主に、データベース全体を参照せずにドメイン モデルをシリアル化できるように、ドメイン モデルをより小さな断片に分割する必要があるためです。これにより、サーバーでの使用が難しくなります。重要なリンクがありません。一部の型はシリアル化できず、クライアントに送信できません。たとえば、「タイプ」または任意のジェネリック クラスです。それらは非ジェネリックである必要があり、Type は文字列として転送される必要があります。これにより、シリアル化のための追加のプロパティが生成されます。それらは冗長で紛らわしいものです。

もう 1 つの問題は、UI 上のエンティティが実際には収まらないことです。私たちはデータバインディングを使用しており、多くのエンティティには、UI の目的のためだけに多くの冗長なプロパティがあります。さらに、エンティティ モデルには、多くの「BrowsableAttribute」などがあります。これは本当に悪いです。

結局はどちらが楽かということだと思います。プロジェクトによっては、問題なく動作し、別の DTO モデルを作成する必要がない場合もあります。

于 2009-05-04T18:28:58.750 に答える
3

ほとんどの場合、依存関係についてです。組織のコア機能構造には独自の機能要件があり、UI は人々がコアを変更および表示できるようにする必要があります。ただし、UI に対応するためにコア自体は必要ありません。(それが発生する必要がある場合、それは通常、コアがプロパティ設計されていないことを示しています。)

私の会計システムには、会社の業務をモデル化するための構造とコンテンツ (およびデータ) があります。その構造は実在し、私が使用する会計ソフトウェアに関係なく存在します。(必然的に、特定のソフトウェア パッケージには、それ自体のために構造とコンテンツが含まれますが、課題の一部は、このオーバーヘッドを最小限に抑えることです。)

基本的に、人にはやるべき仕事があります。DDD は、ジョブの流れと内容に一致する必要があります。DDD とは、実行する必要のあるすべてのジョブを可能な限り完全かつ独立して明示することです。次に、UI によって、ジョブを可能な限り透過的に、可能な限り生産的に実行できるようになることを願っています。

インターフェイスは、適切にモデル化された不変の機能コアに提供される入力とビューに関するものです。

于 2009-05-04T18:30:26.907 に答える
3

くそー、私はこの持続性を誓います。

とにかく、これは同じことのもう 1 つの例です。パルナスの法則では、モジュールは秘密を保持する必要があり、秘密は変更可能な要件です。(ボブ・マーティンは、これの別のバージョンであるルールを持っています。) このようなシステムでは、プレゼンテーションはドメインとは無関係に変更できます。たとえば、価格をユーロで維持し、会社のオフィスではフランス語を使用しているが、標準中国語のテキストでドルで価格を提示したい企業などです。ドメインは同じです。プレゼンテーションは変更できます。したがって、システムのもろさ、つまり、要件の変更を実装するために変更しなければならないものの数を最小限に抑えるには、懸念事項を分離します。

于 2009-05-04T18:45:25.297 に答える
2

プレゼンテーションはドメイン レイヤーを参照する場合がありますが、UI からドメイン オブジェクトへの直接のバインドはあってはなりません。ドメイン オブジェクトは、適切に設計されていれば、多くの場合、データ表現ではなく動作に基づいているため、UI の使用を意図していません。UI とドメインの間にマッピング レイヤーが必要です。MVVM (MVP) は、これに適したパターンです。UI をドメインに直接バインドしようとすると、多くの頭痛の種になる可能性があります。それらには 2 つの異なる目的があります。

于 2009-06-02T01:47:14.593 に答える
1

「 Value Injecter 」などのツールと、ビューを操作する際のプレゼンテーション層の「マッパー」の概念の助けを借りて、コードの各部分をより簡単に理解できます。少しのコードしかない場合、すぐに利点を理解することはできませんが、プロジェクトがますます成長すると、サービスのロジックに入る必要がないビューで作業しているときに非常に満足するでしょう。ビューモデルを理解するためのリポジトリ。View Model は、腐敗防止レイヤーの広大な世界におけるもう 1 つのガードであり、長期的なプロジェクトでは金の価値があります。

ビュー モデルを使用する利点がないと思う唯一の理由は、プロジェクトが小さく、モデルの各プロパティにビューを直接バインドできるほどシンプルである場合です。しかし、将来、要件が変更され、ビュー内の一部のコントロールがモデルにバインドされず、ビュー モデルの概念がない場合は、多くの場所にパッチを追加し始め、レガシー コードを持つようになります。あなたは感謝しません。確かに、リファクタリングを行ってビュー モデルをビュー モデルに変換し、YAGNI の原則に従い、必要がなければコードを追加することはできますが、私にとっては、コードを追加するために従わなければならないベスト プラクティスです。ビュー モデル オブジェクトのみを公開するプレゼンテーション レイヤー。

于 2012-07-02T12:49:02.233 に答える
1

以下のセクション「レイヤー間のデータ伝播」も参照してください。これは説得力のある議論を示していると思います。

http://galaxy.andromda.org/docs/andromda-documentation/andromda-getting-started-java/java/index.html

于 2009-05-04T21:48:07.417 に答える
1

ビューからドメイン エンティティを分離することが良い方法であると私が考える理由について、実際の例を次に示します。

数か月前、一連の 3 つのゲージを通じて土壌サンプル中の窒素、リン、カリウムの値を表示するシンプルな UI を作成しました。各ゲージには、赤、緑、赤のセクションがありました。つまり、各コンポーネントが少なすぎたり多すぎたりする可能性がありますが、中間に安全な緑のレベルがありました。

あまり考えずに、ビジネス ロジックをモデル化して、これら 3 つの化学成分のデータと、3 つのケースのそれぞれで許容されるレベルに関するデータを含む個別のデータ シートを提供しました (使用されている測定単位、つまりモルまたはパーセンテージを含む)。次に、非常に異なるモデルを使用するように UI をモデル化しました。このモデルは、ゲージのラベル、値、境界値、および色に関係していました。

つまり、後で 12 個のコンポーネントを表示する必要が生じたときに、余分なデータを 12 個の新しいゲージ ビュー モデルにマップするだけで、それらが画面に表示されました。また、ゲージ コントロールを簡単に再利用して、他のデータ セットを表示させることもできました。

これらのゲージを自分のドメイン エンティティに直接結合していた場合、上記の柔軟性はまったく得られず、将来の変更は頭痛の種になるでしょう。UI でカレンダーをモデル化するときに、非常によく似た問題に遭遇しました。10 人以上の出席者がいる場合にカレンダーの予定を赤くする必要がある場合、これを処理するビジネス ロジックはビジネス レイヤーに残す必要があり、UI のすべてのカレンダーは、次のように指示されていることを知る必要があります。赤くなる場合、その理由を知る必要はありません。

于 2016-03-14T09:18:47.687 に答える
1

おそらく、UI レイヤーを十分に広い意味で概念化していないでしょう。複数の形式の応答 (Web ページ、音声応答、印刷された文字など) と複数の言語 (英語、フランス語など) の観点から考えてください。

ここで、電話コールイン システムの音声エンジンが、Web サイトを実行しているコンピューター (おそらく Windows) とはまったく異なる種類のコンピューター (たとえば Mac) で実行されているとします。

もちろん、「うちの会社では英語しか気にせず、Web サイトを LAMP (Linux、Apache、MySQL、および PHP) で実行し、全員が同じバージョンの Firefox を使用している」という罠に陥りがちです。しかし、5 年後、10 年後はどうでしょうか。

于 2009-05-04T18:35:39.593 に答える
-1

一般化されたセマンティクスとドメイン固有のセマンティクスの間に追加のマッピングを追加する唯一の賢明な理由は、ドメインのセマンティクスとは異なる一般化された (ただしマッピング可能な) セマンティクスに基づく既存のコード本体 (およびツール) を持っている (アクセスする) ことです。

ドメイン駆動設計は、直交する一連の機能ドメイン フレームワーク (ORM、GUI、ワークフローなど) と組み合わせて使用​​する場合に最適に機能します。ドメインのセマンティクスを公開する必要があるのは、外層の隣接関係だけであることを常に覚えておいてください。通常、これはフロントエンド (GUI) と永続的なバックエンド (RDBM、ORM) です。効果的に設計された介在層は、ドメイン不変であることができ、そうあるべきです。

于 2009-05-04T18:38:15.330 に答える