プレゼンテーション層にMVVMを適用し、アプリケーション全体にDDDを適用したいWPFアプリケーションがあります。アーキテクチャをどのように適用すべきかについて、私は非常に混乱しています。次のデザインを試してみると、現時点では完全に混乱しているように感じますので、アドバイスをいただけますか。
私は4つの層を持っています:
_Presentation Layer
_:これは私のWPFクライアントアプリケーションが存在する場所です。
_Application Layer
_:これは、ビジネスルールのドメインサービスと通信することになっているサービスがあり、CRUDを実行する場所です。これは、Presentation
とDomain
の間の腐敗防止レイヤーとして機能します。 レイヤー。
_Domain Layer
_:ここに、集計、ドメインオブジェクト、およびIsTooOld(Person person)
などのビジネスルールを明らかにするいくつかのサービスがあります。
_Infrastructure Layer
_:これは最下層であり、インフラストラクチャはここにあり、IRepository
、IEntity
などです。 。
これらのDDDベースのレイヤーを使用して簡単なシナリオを実現しましょう。データベースにPersonオブジェクトを配置し、マップし、データベースをCRUDし、人の誕生日を確認して、ユーザーに表示します。
WPFの部分から始めましょう。次のクラスを作成します。
PersonView
:人のXAMLビュー
PersonViewModel
:ViewModel
に機能を提供するPersonView
。 PersonView
はこれにバインドし、このViewModel
はPersonModel
からの値を提供します
PersonModel
:これは私のPersonViewModel
が緊密に結合されているMVVMモデルです。
これは、プレゼンテーション層には十分です。データベースに接続して、personオブジェクトを取得して表示したいと思います。
私は作成する必要があります:
PersonEntity
in _Domain Layer
_:データベースとのマッピングに使用されるデータベースエンティティの集計。 Domain
レイヤーにあります。
Person
in _Domain Layer
_:これはDDDのドメインモデルです。ここにいくつかのロジックを配置しますが、DDDが示唆するようにエンティティオブジェクトを送信したくありません。
わかりました、私はすでに互いにかなり似ている3人のモデルを持っています。データアクセスとサービスについてはどうですか?
PersonService
in _Application Layer
_:プレゼンテーション層がこの層と通信したい場合は、そのPersonModel
(MVVMモデル)からPerson
(ドメインモデル)。次に、アプリケーション層のこのサービスは、Person
(ドメインモデル)をPersonEntity
(エンティティオブジェクト)に変換し、データベースでCRUDを実行します。このサービスは、ドメインレイヤーで別のPersonService
(以下を参照)を使用して、いくつかのビジネスルールをチェック/適用します。
PersonService
in _Domain Layer
_:このレイヤーはPerson
ドメインオブジェクトでのみ機能します。 bool IsTooOld(Person person)
のようなビジネス関連のルールがあります。
要約すると、私は単純なシナリオで7つのクラスになりました。
Presentation.WpfClient.View.PersonView
_Presentation.WpfClient.ViewModel.PersonViewModel
_Presentation.WpfClient.Model.PersonModel
_Application.ApplicationServices.PersonService
_Domain.Application.Services.PersonService
_Domain.Application.Models.Person
_Domain.Application.DbEntities.PersonEntity
_(これを作成した理由は、複雑なドメインオブジェクトのマッピングを使用できないため、ドメインオブジェクトをマッピングする代わりに、ここにいくつかのデータ注釈を配置するだけです)これは非常にぎこちなく感じます。それをどのように再構築し、ドメイン駆動設計とMVVMパターンの両方に利益をもたらすべきかわかりません。私は本当に行き詰まっていて、MVVMとドメイン駆動設計の両方を適用するためのアドバイスや実際の例を本当に楽しみにしています。また、簡単な操作でこれだけの作業を最小限に抑えるための命名規則や戦略についてのフィードバックも受け付けています。
私はまだ2つの具体的な質問があります:
プレゼンテーション層からモデルを削除し(MVVMモデル)、ドメイン層からのモデルのみを使用する必要がありますか(DDDモデル)?この時点でMVVMに違反していませんか?
エンティティ(データベース)モデルをドメインモデルとマージする必要がありますか? DDD違反ではないですか?
更新
私が下した決定:
PersonModel
を削除)PersonEntity
追加されたPersonMappings)。永続性モデルの使用は、単にマッピングするよりもはるかにコストがかかります。ウラジミールの回答から: http://enterprisecraftsmanship.com/2016/04/05/having-the-domain-model-separate-from-the-persistence-model/ を参照してください。最後に、次のようになります。
Presentation.WpfClient.View.PersonView
_Presentation.WpfClient.ViewModel.PersonViewModel
_Application.ApplicationServices.PersonService
_(アプリケーション関連のロジックを含むクラッド)Application.ApplicationServices.Mappings
_(ここにリポジトリの抽象化とマッピングがあります)Domain.Application.People.Person
_(制限されたコンテキスト内の個人オブジェクト、オブジェクトはドメインロジックを処理するのに十分スマートです)これは、単一の概念にはクラスが多すぎます。
プレゼンテーション層からモデルを削除し(MVVMモデル)、ドメイン層からのモデルのみを使用する必要がありますか(DDDモデル)?この時点でMVVMに違反していませんか?
はい、これは多くの場合、特にWCFのような通信メカニズムを使用しない場合に望ましい解決策です。 MVVMはモデルパーツの特定の実装を強制しないため、ここでは違反はありません。
エンティティ(データベース)モデルをドメインモデルとマージする必要がありますか? DDD違反ではないですか?
また、はい。エンティティを2つ(ドメインエンティティと「永続性」エンティティ)に分離すると、通常、過度の複雑化と貧血のドメインモデルが発生します。これについての詳細は次のとおりです。 ドメインモデルを永続性モデルから分離する 。
全体として、 this の例を確認することをお勧めします。これはまさにあなたが必要としているもののように見えます:MVVMとDDDを使用してWPFで書かれた本格的なアプリケーション。
DDDは、複雑なビジネス上の問題を処理するのに最も有益です。実際のプロジェクトでは、ドメインの複雑さに応じて、より柔軟な方法で使用する必要があります。それを採用するために、複数の戦略のアプローチを使用したいと思います。
ほとんどの場合、データ構造の変更がほとんどないCRUDデータに関するものです。私は使用するだけです:
プレゼンテーション層:ViewModel
サービスレイヤー:ViewModel <-> Dominオブジェクト
ドメインレイヤー:エンティティと同じドメインオブジェクト
ドメインオブジェクトに重要で再利用可能なビジネスロジックが多数ある、より複雑なドメインの場合は、コアサービス(Domain.Application.Services.PersonServiceなど)を追加します。
プレゼンテーション層とドミン層の間でデータを簡単にマッピングするために、プロセスデータに必要な複雑なビジネスロジックもある場合。 Presentation.WpfClient.Model.PersonModelと同様に、サービスレイヤーに別のモデルを追加します。
つまり、基本的に、現在使用しているアーキテクチャは、Personドメインがプロジェクト内で非常に複雑な場合に対処する準備ができています。しかし、私はあなたの説明からそれを今のところ見ることができません。
あなたの質問に答えるには:
MVVMモデルのPresentation.WpfClient.Model.PersonModelを削除できます。この場合、ドメインオブジェクトはモデルであり、ViewModelとしてPresentation.WpfClient.ViewModel.PersonViewModelがあるため、MVVMに違反しません。
Personドメインに複雑なビジネスロジックがない場合は、EntityをDomainオブジェクトとマージできます。
最初の質問では、ドメインレイヤーモデルをMVVMモデルとして使用しても、MVVMに違反することはありません( モデルの定義はこちらを参照 )
このテーマの詳細と2番目の質問への回答については、次を参照してください。 エンティティVSドメインモデルVSビューモデル