web-dev-qa-db-ja.com

ドメイン駆動設計-レイヤーはどのように整理する必要がありますか?

私はソフトウェア開発に非常に慣れていません。階層化アーキテクチャは、オブジェクト指向ソフトウェア開発のプロセスで発生する複雑さを軽減し、言うまでもなく、コードを整理しておくための優れた方法だと思います。

ドメインドリブンデザインのアプローチについて学びたいと思っています。いくつかの問題にぶつかって、自分自身を紹介しました(もちろん、初心者レベルの問題です)。
ここにあります -

人に関連するデータをデータベースに保存し、人の詳細をWPF DataGridに表示するアプリケーションを構築したいと思います(確かに、DDDはそのような規模のアプリ用ではなく、私のようなアマチュアにとって単純なものにするためです)。そこで、次のようなドメインクラス「Person」を作成しました。

    public class Person
    {
        public Person(dataType paramA)
        {
            this.PropertyA = paramA;
        }

        private dataType _fieldA;
        public dataType PropertyA
        {
            //encapsulates _fieldA    
        }

        public dataType PropertyX
        {        
            //some code that manipulates private field    
        }

        private dataType MethodPQR(dataType param)
        {        
            //some code    
        }
    }

今、DDDの私の理解は、アーキテクチャ(それの最も単純なバージョン)は次のようになるべきだと言っています(私が間違っている場合は修正してください)-
enter image description here

注意:

  1. DataGridObservableCollectionにバインドして、あらゆる種類の変更を即座に反映したい。

  2. これはWPFアプリケーションですが、必ずしもMVVMパターンである必要はありません。故意にコードを背後で使用したいと考えています。

私の質問は-

  1. どのような種類のコードがApplication Layerに属していますか?

  2. 私の推測では、ドメインオブジェクト(つまりObservableColletion)のPersonItmsSourceDataGridとしてバインドしないでください。次に、ドメインオブジェクトからどのタイプのオブジェクトを抽出する必要がありますか?

  3. Presentation LayerDomain Layerの分離を維持するには、おそらくnever instantiate domain objects directly in the presentation layerのような規則があります。では、non-directのアプローチは何ですか?

  4. コードビハインドがApplication Layerと通信する場合、Application LayerData Repositoryと通信する必要がありますか?しかし、データアクセスに関連するではないある種のドメインアクセスが必要な場合(このアプリにはないかもしれませんが、発生する可能性がありますよね?)そのシナリオでは、Domain LayerApplication Layerが話し合うべきXの人(サブレイヤー/モジュール)は誰ですか?

私の質問は非常にアマチュアレベルのものであることは知っていますが、それらは確かに、明確な状況を把握するために直面​​している問題から生じた質問です。ですので、時間があればどなたでもご回答いただければ幸いです。

EDIT:Data RepositoryDomain Modelの参照を持つ必要があるかどうかはわかりません。

36
atiyar

より「古典的な」DDDに関して言えば、はい、ドメインオブジェクトは通常、ドメイン外では許可されていません。ただし、ドメインオブジェクトがプレゼンテーション層で使用されないことは絶対的な規則ではありません。たとえば、ネイキッドオブジェクトは、ドメインオブジェクトが直接使用される一連の考え方を表しています。私自身は主にドメインオブジェクトが直接使用されないという哲学に固執しているので、彼らが提案するすべてのプラクティスに精通していません。個人的にはドメインオブジェクトに直接バインドすることはお勧めできないと思いますが...だけ覚えておいてください誰もがこれを要件と見なしているわけではありません。

ドメイン自体の外部のドメインオブジェクトを許可しない場合は、通常、ドメイン動作を持たない単純なプロパティのみのクラスであるDTOまたはデータ転送オブジェクトを使用します。多くの場合、DTOはドメインモデル構造を正確に反映しますが、そうする必要はありません。

ビジネスロジックはドメインモデルに実装されることになっているため、アプリケーション層にあるものの多くは、さまざまなサービスの調整に関係しており、通常はクライアントアプリケーションとの間でデータをやり取りします。多くの人々は何らかの形式のSOAまたは少なくともこのためにWebサービスを使用します。これらはリポジトリを呼び出しますが、リポジトリの呼び出しから返されたドメインオブジェクトを取得してプロパティをコピーするには、アセンブラなどの他のコンポーネントも必要です値はDTOに変換され、シリアル化されて呼び出し元に返されます。呼び出し元は多くの場合、プレゼンターまたはコントローラーですが、MVCまたはMVPを使用していない場合、呼び出し元はプレゼンテーションレイヤーにいます。逆のトリップはより複雑です-UI更新を表すDTOまたは追加する新しいオブジェクトを表すDTOを送り返すことができます。これらのやり取りを仲介することは、主にアプリケーション層の目的です。

ドメイン層の「非データアクセス」に関する限り、いくつかの典型的な例があります。ほとんどの人は通常、ドメインサービスとして考えることができる「X」コンポーネントを参照します。ドメインサービスは、ドメインモデルに近いこと、および実際のビジネスロジックが存在することで、アプリケーションサービスとは異なります。

たとえば、アプリケーションに注文の種類が含まれている場合、実際には2つの問題があります。注文の発行と注文の履行です。アプリケーションサービスは、UIへの注文の作成に必要なデータの転送を仲介し、ユーザーが希望する注文を返します。しかし、それはデータ転送を仲介するだけであり、それがアプリケーションサービスの終わりです。次に、ビジネスルールを適用し、実際にその注文を満たすために必要な追加のドメインオブジェクトを構築するために、ドメインサービスが必要になる場合があります。

一般的に私は多くのシナリオに適用できる有用な概念または比喩であることを見つけます-アプリケーションサービスは、要求submissionのみに関して、ある種の要求を容易にします。一方、ドメインサービスは、実際のリクエストフルフィルメントを容易にします。

私が遭遇した、またはすぐに想像できるデータ指向以外の「アクセス」の他の唯一のモードは、プロセス指向の機能です。これはすべてのアプリケーションで発生するわけではありませんが、特定の分野で蔓延しています。たとえば、私が勤務するヘルスケアでは、臨床データと臨床プロセスの両方を管理する重要な要素を組み込んだアプリケーションが必要になる場合があります。この問題を解決するには、そのプロセスをドメインモデルの一部に重点を置かず、代わりにさまざまなツールを使用します。

OOP手法は、実際のプロセス自体にはあまり適していません。プロセスにデータを提供したり、プロセスからデータをキャプチャしたりするのに役立ちます。オブジェクト指向も結局主に名詞指向です。リアルタイムのプロセス管理には、「名詞指向プログラミング」よりも「動詞指向プログラミング」が必要です。ワークフローツールは、動詞指向のツールであり、データ集約型とプロセス集約型の両方のアプリケーションのドメイン駆動モデルを補完できます。私はC#DDDモデルとWorkflow Foundationモデルの両方を含む多くの作業を行っていますが、これは特定の種類のアプリケーションでのみ必要です。多くの一般的なビジネスアプリは、ドメインモデルとサービスのみを必要とします。

最後に、DDDの最も重要な側面は、技術やアーキテクチャではありません。その真の核心は、ユビキタス言語とドメインの専門家との対話(私の強い意見ではDIRECTの対話)を中心に展開し、重要なドメインの知識を抽出します。 (私の意見ではDDDを行うと主張しているほとんどの企業は、ビジネスと開発が直接対話することを許可しないことを拒否しているためではありませんが、それは別のトピックです...)それは、ドメイン知識の抽出と統合ではなく、 DDDを従来のOOPから実際に分離するテクニックであり、DDDの実際の値が発生する場所です。

編集する

リポジトリの使用に関する限り、図は正しいです。通常、アプリケーション層は常にドメインオブジェクトのリポジトリを通過します。まず第一に、アプリケーションにデータをもたらすことができなければならず、ほとんどのアプリケーションはある程度のクエリ機能も必要とします。

ドメイン層OTOHは通常、リポジトリと対話しません。通常、ドメインモデルは自己完結型で、特定のテクノロジーから切り離される必要があります。つまり、「純粋なドメイン知識」を表す必要があります。永続性は本質的にある種の特定のテクノロジーと密接に結びついているため、一般的に人々はドメインモデルに永続性の実装がないように努めています。リポジトリがありますが、通常、ドメインモデルでリポジトリメソッドを呼び出したくありません。

ドメインモデル自体の中で、オブジェクトは新しいオブジェクト(直接またはファクトリを通じてインスタンス化される可能性がある)として取得されるか、または関連付けをトラバースすることによって取得されます。新しいオブジェクトを作成するときに、必要なすべてをコンストラクタに渡すことが実用的でない場合があるため、ドメインモデル自体の中で何らかのデータアクセスが必要になる場合があります。通常、ドメインモデルにデータアクセスが提供されても、データレイヤーの実装から切り離されたままになるように、インターフェイスを介してデータサービスを渡すのが一般的です。しかし、ほとんどの場合、ドメインオブジェクトは、既にインスタンス化されている他のドメインオブジェクトと連携して動作します。

42
Sisyphus