アプリケーション層vsドメイン層?


47

私はEvansによるドメイン駆動設計を読んでおり、階層アーキテクチャについて議論している部分にいます。アプリケーション層とドメイン層は異なり、別々にする必要があることに気付きました。私が取り組んでいるプロジェクトでは、それらは混ざり合っており、本を読むまで違いを伝えることはできません(そして、今では私にとって非常に明確だとは言えません)。

私の質問は、どちらもアプリケーションのロジックに関するものであり、技術的側面とプレゼンテーションの側面はきれいであると想定されているため、これら2つの境界線を引くことの利点は何ですか?

回答:


36

私は最近自分でDDDを読みました。このセクションにたどり着いたとき、エヴァンスが行ったのと同じ4層アーキテクチャを発見したことを知り、嬉しく驚きました。@lonelybugが指摘したように、ドメインレイヤーはシステムの他の部分から完全に分離する必要があります。ただし、UI固有の値(クエリ文字列、POSTデータ、セッションなど)をドメインオブジェクトに変換する必要があります。これは、アプリケーション層が機能する場所です。それは、UI、データレイヤー、およびドメイン間で相互に変換し、ドメインをシステムの他の部分から効果的に隠すことです。

現在、ほとんどすべてのロジックがコントローラー内にある多くのASP.NET MVCアプリケーションがあります。これは、従来の3層アーキテクチャを実装しようとして失敗した試みです。コントローラーは、UI固有の問題が非常に多いため、単体テストが困難です。実際、「Http Context」値に直接関係しないようにコントローラーを作成することは、それ自体が重大な課題です。理想的には、コントローラーは変換を実行し、作業を調整し、応答を吐き出すだけです。

アプリケーション層で基本的な検証を行うことも理にかなっています。ドメインは、値が意味をなすと想定しても構いません(これはこの顧客の有効なIDであり、この文字列は日付/時刻を表しますか)。ただし、ビジネスロジックを含む検証(過去に飛行機のチケットを予約できますか?)は、ドメインレイヤー用に予約する必要があります。

マーティンファウラーは、実際、最近のほとんどのドメインレイヤーがどれだけ平坦かについてコメントしています。ほとんどの人はアプリケーション層が何であるかさえ知らなくても、多くの人がかなり物の悪いドメインオブジェクトと、異なるドメインオブジェクトの作業を調整する複雑なアプリケーション層を作成していることに気付きます。私はこれを自分で犯しています。重要なことは、いくつかの本があなたに言ったので、層を構築することではありません。考え方は、責任を特定し、それらの責任に基づいてコードを分離することです。私の場合、「テスト層」の種類は、単体テストを増やすにつれて自然に進化しました。


9
ここであなたが述べていることは正しいとは思いません:「しかし、何かがUI固有の値(クエリ文字列、POSTデータ、セッションなど)をドメインオブジェクトに変換する必要があります。これがアプリケーション層の出番です」あなたが言及しているのは、DDDの用語では「プレゼンテーション」レイヤーです。アプリケーション層は、配管、同時実行性、および横断的な関心事に対処することになっており、ドメイン層の単なる小さなラッパーです。説明する内容は、プレゼンテーションレイヤーの(サブ)レイヤーに対応します。
エリジウムをむさぼり食った

23

マーティン・ファウラーのエンタープライズ設計のパターンから取った、最も一般的な層は次のとおりです。

  • プレゼンテーション-これらは、アプリケーションの対話インターフェイスを生成するビュー、プレゼンテーションテンプレートです(アプリケーションが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 モデル、ビュー、コントローラー、


17

ドメイン層のモデル事業、アプリケーションの。これは、ルールの明確な解釈である必要があります。コンポーネントダイナミクスであり、特定の瞬間の状態が含まれています。

アプリケーション層は、特定のアプリケーションのタスクを達成するために行われるために必要なジョブを定義し、「心配」されます。主に、必要なドメイン作業を委任し、他の(外部または非)サービス対話します。

以下のために、例えば、私の金融ソフトウェアアプリケーションは、モデルエンティティ(DDD [89]で定義されたエンティティ)の状態を変更するためのユーザ操作を有します。

  • 「最高経営責任者は財務提案を承認できます」。

しかし、アプリケーションプロセスとして、この操作のすべてのモデル結果に加えて、アプリケーションの他のユーザーに内部通信を送信する必要があります。この種の作業は、アプリケーション層で「調整」されます。ドメイン層がメッセージングサービスを指示することを考えたくないでしょう。(そして確かにこれはプレゼンテーション層の責任ではありません)。いずれにせよ、1つのことは確かです。ドメインレイヤーはコアビジネスに関するものであり、プレゼンテーションレイヤーはユーザーコマンドの解釈と結果の提示に関するものなので、新しいレイヤーが必要です。

ノート:

  • ビジネスは、その意味の複数の解釈に頻繁につながる単語の1つですが、確かに、DDDで多くの例と話を見つけることができます。
  • DDDは、Eric EvansによるDomain-Driven Design本と、ページ番号の角括弧内の番号の略です。

6

ドメインレイヤーは分離レイヤーとして設計する必要があります。つまり、ビジネスロジックとルールは、コード(アプリケーションレイヤー、プレゼンテーションレイヤー、インフラストラクチャレイヤー)の変更による影響を受けません。

アプリケーション層は、システム(アプリケーション)インターフェース(APIやRESTfulのように考えてください)ができることに関するいくつかの機能を提供するように設計されていると想定されています。たとえば、ユーザーはシステムにログインできます。このアプリケーションアクション(ログイン)では、アプリケーションレイヤーコードはドメインレイヤー(またはインフラストラクチャレイヤー)のクライアントコードになり、ユーザードメインオブジェクトを取得し、このオブジェクトのメソッドを適用して「ログイン」機能。

また、アプリケーション層は分離層として設計する必要があります。これは、アプリケーションの動作がコード(プレゼンテーション層、ドメイン層、インフラストラクチャ層)の変更によって影響を受けないことを意味します。


2
少なくともDomain-Driven Design(Evans)などの文献では、レイヤーは一方向の依存関係を持っていることが認められています...実際、ある時点でコードは何かに依存しています。UIはアプリケーションに依存しますが、その逆ではありません。アプリケーションはドメインに依存しますが、その逆ではありません。その逆ではなく、インフラストラクチャ上のドメイン。

1
依存関係とは、プログラミングの方法に関するものであり、分離層とは、システム層の設計方法に関するものです。プログラミングの際、最上位層のコードは実装クラスではなく下位層のインターフェースに依存する必要があるため、1つの方法の依存関係によって分離の概念が破られることはありません。
-stevesun21

それは素晴らしいことであり、すべて紙の上にありますが、実際には、ビジネス要件は、プレゼンテーション層を介して、時にはストレージ層に至るまで変化するような方法で、アプリケーション層のインターフェースに影響を与える可能性のある変更をもたらします。それは私が得ていたすべてです

分離層の設計は、将来変更が許可されないという意味ではありません。反対に、変更がはるかに簡単になります。テストが容易になり、作品を簡単に推定できます。はい、新しいビジネス要件は、上から下に変更する必要があるかもしれないことを意味します。以前の既存の機能の実装方法ではありませんか?SOLIDの原則に基づいて各レイヤーを設計できる場合、下のレイヤーの既存の関数を再利用できることがわかります。
stevesun21

3

ドメインドリブンモデリングのポイントは、重要なドメインモデルを分離し、他のレイヤーや他のアプリケーションの懸念に依存せずに存在させることです。

これにより、気を散らすことなく、ドメイン自体に集中することができます(UIと永続化サービス間の調整など)。


次に、データソース(ORM)はドメイン内にありますか?
メイコン

@Maykonn-そうかもしれない。ただし、ORMはデータのソースではありません。これは、コードと実際のデータソース(リレーショナルデータベース)の間のツールです。データへのアクセス方法はドメインの問題ではないはずです-ビルダーと工場はそれに対処できます(ORMがある場合はORM)。
Oded

同意する。そして、データソースとORMについて間違っていました。ありがとう!
メイコン

3
  • アプリケーション層ドメイン層はどちらも実装の範囲内にあります。
  • アプリケーション層はAPIとして機能します。
  • ドメインレイヤーは、APIの実装として機能し、ビジネスロジックを含むため、ビジネスロジックレイヤーとも呼ばれます

ここに画像の説明を入力してください


決してそうではありません。...私は啓発されたと感じています
ニコス

2

これらの境界の主な理由は、懸念の分離です。データストアにアクセスするコードは、データストアへのアクセスについてのみ心配する必要があります。データにルールを適用する責任はありません。さらに、UIはUI内のコントロールを更新し、ユーザー入力から値を取得し、それらをドメインレイヤーが使用できるものに変換します。ドメイン層によって提供される操作を呼び出して、必要なアクションを実行する必要があります(このファイルを保存するなど)。呼び出されるWebサービスは、伝送メディアからドメインレイヤーが使用できるものに変換し、ドメインレイヤーを呼び出す必要があります(ほとんどのツールがこの作業の多くを行います)。

この分離を適切に実装すると、他のコードに影響を与えずにコードの一部を変更できるようになります。たとえば、返されるオブジェクトのコレクションの並べ替え順序を変更する必要がある場合があります。データ操作を担当するレイヤー(通常はビジネスロジックレイヤー)がこの処理を行うことを知っているため、コードを変更する必要がある場所を簡単に特定できます。また、データストアまたはドメインを使用するアプリケーション(上記の例のUIとWebサービス)から取得する方法を変更する必要もありません。

最終的な目標は、コードを可能な限り保守しやすくすることです。

サイドノートとして、ドメインの特定のレイヤーにピジョンホールできないものもあります(ログ、検証、承認など)。これらのアイテムは一般に横断的関心事と呼ばれ、場合によっては、他のすべてのレイヤーが表示および使用できる単独のレイヤーとして扱うことができます。

個人的には、階層化アプローチは時代遅れであり、サービスアプローチの方が優れていると思います。砂の中に誰が何をするかについての厳しい線が引かれていますが、それはあなたを階層的にすることを強制しません。たとえば、アプリケーションの観点から、発注書サービス、請求サービス、配送サービスは、これらすべてのサービスがドメインを表しており、上記で説明した責任の延期はこの文脈ではまだ有効であり、変更されたばかりですドメインが複数の場所に存在し、さらに懸念の分離の概念を活用していること。


私は認可ロジックの配置に興味があり、私が理解しようとしていることから、それは「アプリケーション層」に収まります。そのロジック層に含めるのが最善ではない理由についての洞察を共有していただけますか?

1
それがこのサイトにぴったりの質問です。誰もが答える機会があるように、それを投稿すべきです。
チャールズランバート

@tuespetreその投稿へのリンクを提供できますか?
drizzie
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.