回答:
私は最近自分でDDDを読みました。このセクションにたどり着いたとき、エヴァンスが行ったのと同じ4層アーキテクチャを発見したことを知り、嬉しく驚きました。@lonelybugが指摘したように、ドメインレイヤーはシステムの他の部分から完全に分離する必要があります。ただし、UI固有の値(クエリ文字列、POSTデータ、セッションなど)をドメインオブジェクトに変換する必要があります。これは、アプリケーション層が機能する場所です。それは、UI、データレイヤー、およびドメイン間で相互に変換し、ドメインをシステムの他の部分から効果的に隠すことです。
現在、ほとんどすべてのロジックがコントローラー内にある多くのASP.NET MVCアプリケーションがあります。これは、従来の3層アーキテクチャを実装しようとして失敗した試みです。コントローラーは、UI固有の問題が非常に多いため、単体テストが困難です。実際、「Http Context」値に直接関係しないようにコントローラーを作成することは、それ自体が重大な課題です。理想的には、コントローラーは変換を実行し、作業を調整し、応答を吐き出すだけです。
アプリケーション層で基本的な検証を行うことも理にかなっています。ドメインは、値が意味をなすと想定しても構いません(これはこの顧客の有効なIDであり、この文字列は日付/時刻を表しますか)。ただし、ビジネスロジックを含む検証(過去に飛行機のチケットを予約できますか?)は、ドメインレイヤー用に予約する必要があります。
マーティンファウラーは、実際、最近のほとんどのドメインレイヤーがどれだけ平坦かについてコメントしています。ほとんどの人はアプリケーション層が何であるかさえ知らなくても、多くの人がかなり物の悪いドメインオブジェクトと、異なるドメインオブジェクトの作業を調整する複雑なアプリケーション層を作成していることに気付きます。私はこれを自分で犯しています。重要なことは、いくつかの本があなたに言ったので、層を構築することではありません。考え方は、責任を特定し、それらの責任に基づいてコードを分離することです。私の場合、「テスト層」の種類は、単体テストを増やすにつれて自然に進化しました。
マーティン・ファウラーのエンタープライズ設計のパターンから取った、最も一般的な層は次のとおりです。
プレゼンテーション-これらは、アプリケーションの対話インターフェイスを生成するビュー、プレゼンテーションテンプレートです(アプリケーションがWebサービスまたはRMIを介して他のシステムからアクセスされる場合、ユーザーインターフェイスではない場合があるため、対話を使用しています)。これには、アクションの実行方法と方法を決定するコントローラーも含まれます。
ドメイン-これは、ビジネスルールとロジックが存在する場所、ドメインモデルが定義されている場所などです。
データソース-これはデータマッピングレイヤー(ORM)およびデータソース(データベース、ファイルシステムなど)です。
3つのレイヤー間の境界をどのように描画しますか:
モデルまたはドメインオブジェクト内にプレゼンテーション固有のロジックを配置しないでください
ページやコントローラー内にロジックを配置しないでください。つまり、オブジェクトをデータベースに保存したり、データベース接続を作成したりするロジックなど、プレゼンテーションレイヤーが脆弱でテストが困難になるロジックを配置しないでください。
モデルからデータソースへのアクセスとアクションを分離できるORMを使用します
シンコントローラーに従う-ファットモデルパラダイム、コントローラーは実行されない実行プロセスを制御するためのものです。詳細はhttp://www.littlehart.net/atthekeyboard/2007/04/27/fat-models-skinny-controllers/およびhttp://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model モデル、ビュー、コントローラー、
ドメイン層のモデル事業、アプリケーションの。これは、ルールの明確な解釈である必要があります。コンポーネントダイナミクスであり、特定の瞬間の状態が含まれています。
アプリケーション層は、特定のアプリケーションのタスクを達成するために行われるために必要なジョブを定義し、「心配」されます。主に、必要なドメイン作業を委任し、他の(外部または非)サービスと対話します。
以下のために、例えば、私の金融ソフトウェアアプリケーションは、モデルエンティティ(DDD [89]で定義されたエンティティ)の状態を変更するためのユーザ操作を有します。
しかし、アプリケーションプロセスとして、この操作のすべてのモデル結果に加えて、アプリケーションの他のユーザーに内部通信を送信する必要があります。この種の作業は、アプリケーション層で「調整」されます。ドメイン層がメッセージングサービスを指示することを考えたくないでしょう。(そして確かにこれはプレゼンテーション層の責任ではありません)。いずれにせよ、1つのことは確かです。ドメインレイヤーはコアビジネスに関するものであり、プレゼンテーションレイヤーはユーザーコマンドの解釈と結果の提示に関するものなので、新しいレイヤーが必要です。
ノート:
ドメインレイヤーは分離レイヤーとして設計する必要があります。つまり、ビジネスロジックとルールは、コード(アプリケーションレイヤー、プレゼンテーションレイヤー、インフラストラクチャレイヤー)の変更による影響を受けません。
アプリケーション層は、システム(アプリケーション)インターフェース(APIやRESTfulのように考えてください)ができることに関するいくつかの機能を提供するように設計されていると想定されています。たとえば、ユーザーはシステムにログインできます。このアプリケーションアクション(ログイン)では、アプリケーションレイヤーコードはドメインレイヤー(またはインフラストラクチャレイヤー)のクライアントコードになり、ユーザードメインオブジェクトを取得し、このオブジェクトのメソッドを適用して「ログイン」機能。
また、アプリケーション層は分離層として設計する必要があります。これは、アプリケーションの動作がコード(プレゼンテーション層、ドメイン層、インフラストラクチャ層)の変更によって影響を受けないことを意味します。
ドメインドリブンモデリングのポイントは、重要なドメインモデルを分離し、他のレイヤーや他のアプリケーションの懸念に依存せずに存在させることです。
これにより、気を散らすことなく、ドメイン自体に集中することができます(UIと永続化サービス間の調整など)。
これらの境界の主な理由は、懸念の分離です。データストアにアクセスするコードは、データストアへのアクセスについてのみ心配する必要があります。データにルールを適用する責任はありません。さらに、UIはUI内のコントロールを更新し、ユーザー入力から値を取得し、それらをドメインレイヤーが使用できるものに変換します。ドメイン層によって提供される操作を呼び出して、必要なアクションを実行する必要があります(このファイルを保存するなど)。呼び出されるWebサービスは、伝送メディアからドメインレイヤーが使用できるものに変換し、ドメインレイヤーを呼び出す必要があります(ほとんどのツールがこの作業の多くを行います)。
この分離を適切に実装すると、他のコードに影響を与えずにコードの一部を変更できるようになります。たとえば、返されるオブジェクトのコレクションの並べ替え順序を変更する必要がある場合があります。データ操作を担当するレイヤー(通常はビジネスロジックレイヤー)がこの処理を行うことを知っているため、コードを変更する必要がある場所を簡単に特定できます。また、データストアまたはドメインを使用するアプリケーション(上記の例のUIとWebサービス)から取得する方法を変更する必要もありません。
最終的な目標は、コードを可能な限り保守しやすくすることです。
サイドノートとして、ドメインの特定のレイヤーにピジョンホールできないものもあります(ログ、検証、承認など)。これらのアイテムは一般に横断的関心事と呼ばれ、場合によっては、他のすべてのレイヤーが表示および使用できる単独のレイヤーとして扱うことができます。
個人的には、階層化アプローチは時代遅れであり、サービスアプローチの方が優れていると思います。砂の中に誰が何をするかについての厳しい線が引かれていますが、それはあなたを階層的にすることを強制しません。たとえば、アプリケーションの観点から、発注書サービス、請求サービス、配送サービスは、これらすべてのサービスがドメインを表しており、上記で説明した責任の延期はこの文脈ではまだ有効であり、変更されたばかりですドメインが複数の場所に存在し、さらに懸念の分離の概念を活用していること。