3

現在のプロジェクトでDDDのプリンシパルを適用しようとしています。うまくいけば意味のある例を使って、この(長い間)質問をしてみます。

新しいメンバーを作成するとき、私のプレゼンテーション層は、アプリケーション層で定義されているMemberService.CreateMember(MemberDTO memberDTO)を呼び出します。

私のプレゼンテーション層には次のようなものがあります。

MemberDTO member = new MemberDTO(); //Defined in Application Layer

member.Username = username;
member.Password = password;
//...etc

私のアプリケーション層は、ドメイン層で次のファクトリメソッドを呼び出してメンバーを作成します。

public static Member MemberFactory.CreateMember(string memberDTO.Username, string memberDTO.Password...)
{
  var member = new Member(); //Domain.Model.Member

  member.Id = GenerateIdentity();

  member.Username = memberDTO.Username;

  //... etc

  return member;
}

メンバーはMemberService(アプリケーション層)に戻され、MemberService(インフラストラクチャ層のリポジトリ)に保存され、MemberDTOにマップされ(AutoMapperを使用)、プレゼンテーション層に戻されます。

したがって、プレゼンテーション層はMemberDTOで値を設定し、次にドメイン層(ファクトリ経由)は個々のパラメーターを取得してメンバーの値を設定します。ファクトリがなければ簡単ですが、ここでIDを生成しています。IDを生成する代わりにドメインサービスを作成するのは間違っているでしょうか?たとえば、MemberService.CreateMember(MemberDTO memberDTO)メソッドを次のように変更します。

public MemberDTO CreateMember(MemberDTO memberDTO)
{
   var member = MemberFactory.CreateMember(memberDTO.Username, memberDTO.Password); 
   //Domain.Model.Member

   SaveMember(member);

   //Pass DTO to presentation layer
   return Mapper.Map<Member, MemberDTO>(member);
}

これに:

public MemberDTO CreateMember(MemberDTO memberDTO)
{
   var member = new Member(); //Domain.Model.Member

   Mapper.Map<MemberDTO, Member>(memberDTO);

   //Add this method into a Domain Service to generate the ID and any other defaults
   Domain.MemberService.Initialise(member);

   SaveMember(member);

   //Pass DTO to presentation layer
   return Mapper.Map<Member, MemberDTO>(member);
}

答えは単純な「はい」または「いいえ」である可能性がありますが、長い質問で申し訳ありません。

4

3 に答える 3

2

DDD に関連して、この ID がドメイン ID (つまり、境界コンテキストに基づいてユーザーを定義するもの) でない場合、それはドメイン モデルに属しません。私が見たほとんどの場合、ユーザー名は境界付けられたコンテキストでのユーザーの ID であり、生成された ID はデータベース アクセスのために行われます。これはあなたのケースであると思われます。私が正しければ、生成された ID はインフラストラクチャの問題であり、リポジトリの実装によって行われるべきです。ドメインには、この生成された ID の概念がありません。

一方、ユーザー名がコンテキスト内のユーザーの ID であり、何らかのドメイン式を使用してその ID を生成したいとします。この場合、ID の生成はドメイン サービス メソッドになります。ドメイン オブジェクトのインスタンスに属していないからです。生成された ID はファクトリに渡され、次のようになります。

public MemberDTO CreateMember(MemberDTO memberDTO)
{
   //Domain.Model.Member
   var member = MemberFactory.CreateMember(MemberService.GenerateUserName(), memberDTO.Password); 

   SaveMember(member); //Repository method?

   //Pass DTO to presentation layer
   return Mapper.Map<Member, MemberDTO>(member);
}

要約すると、答えはノーです。ID が境界付けられたコンテキストの実際の ID であると仮定して、ID を生成するドメイン サービスを作成することは間違いではありません。実際、これはあなたがすべきことです。ただし、ID が境界付けられたコンテキストのユーザーの ID でない場合は、ID の生成方法、データベースへのアクセス方法、およびドメイン モデルとの間の変換方法について、リポジトリに任せてください。

于 2013-01-02T15:04:39.647 に答える
1

簡単な答え: はい、DTO オブジェクトをファクトリに渡すことができます。

長い答え: ドメイン オブジェクト ファクトリは、完全に初期化されたドメイン オブジェクトの作成を担当します。ただし、必要な情報を提供できる限り、任意の形式の入力を自由に選択できます。この場合、ファクトリにいずれかのメソッドを含めるかどうかは個人的な選択の問題です: - public Member CreateMember(string userName, string password, ...) {...} - public Member CreateMember(MemberDTO memberDTO) {.. .}

階層化の観点からは、ドメイン オブジェクト ファクトリはドメイン モデルの一部です。したがって、ドメインモデル層とアプリケーション層のさまざまなオブジェクトによって使用および依存される可能性があります。あなたが説明したことから、MemberService はアプリケーション (サービス) レイヤーに属しているようです。作成ロジックをそこに移動すると、難しい依存関係の問題が見つかる場合があります。たとえば、Booking ドメイン オブジェクトが確認時に Member ドメイン オブジェクトを作成する場合、Booking オブジェクトが MemberService に依存することになる可能性がありますが、これはお勧めできません。ここに例を示します: http://thinkinginobjects.com/2012/09/05/abstract-factory-in-domain-modelling

少し戻って、問題をある観点から見てみると、MemberDTO と MemberService がアプリケーションにどのようなサービスを提供しているのかを正確に尋ねたいと思います。DTO オブジェクトは一連のデータ フィールドのラッパーとして使用されますか? MemberService は単に create 呼び出しをファクトリとリポジトリに委任しているだけですか? 答えが「はい」の場合、MemberDTO と MemberService をまとめて取り除き、プレゼンテーションを残して MemberFactory と MemberRepository を直接呼び出すと、コードがはるかに単純になります。ここでは多くの仮定を立てていますが、プレゼンテーション レイヤーとサービス レイヤーが物理的に分離されている場合でも、DTO とサービスが望ましい場合があります。

于 2013-01-02T22:53:37.497 に答える
1

追加の複雑さを必要とする複雑なドメインが表示されないため、DDD に関連するこの質問についてはわかりません。ただし、ID の生成を別の構造で定義するという議論もあるでしょうが、これは主に単一責任 (SRP) を実現するためのものです。

という名前のインターフェースを作成することをお勧めしますIGenerateMemberIdentity。次に、その複雑さを分離してテストできます。この機能が工場に属していないというあなたの直感は正しいと思います。これが複雑なルーチンである場合、オブジェクトの作成に関するものではないようです。

しかし、私にとってInitialize静的メソッドはコードの匂いのように思えます。その機能を提供するインターフェイスの背後に依存関係を挿入することをお勧めします。

あなたの質問に具体的に答えるために。いいえ、間違っていないと思います。実際、純粋なビジネス機能を維持するために複雑さをモデル化することは、DDD が得意とするところです。

于 2013-01-01T18:00:31.587 に答える