2012-03-27 3 views
1

A,AbstractElement,,YおよびZの集計を持っています。ルートエンティティはAであり、リストもAbstractElementです。エンティティX,YおよびZは、AbstractElementから継承します。 XYZのインスタンスをAのインスタンスに追加する必要があります。 1つのアプローチは、タイプごとに1つの方法、すなわちaddX,addYおよびaddZを使用することです。これらのメソッドは、引数として、X,YおよびZのインスタンスを作成するために必要な値をとります。しかし、AbstractElementから継承する新しいタイプを追加するたびに、エンティティAを変更する必要があります。そのため、これは最善の解決策ではないと思います。集団ルートと子エンティティのインスタンス作成

もう1つの方法は、の抽象的な追加メソッドを使用して、AbstractElementのインスタンスを追加することです。しかし、この場合、このメソッドは引数として、AbstractElementのインスタンスを取ります。このメソッドは、DDDルール/推奨に従って、集約の外にあるエンティティによって呼び出されるため、AbstractElementのインスタンスを作成する権限を与えられた外部エンティティはありますか?私はEric Evansの本で、外部エンティティがルート以外の集約のエンティティの参照を保持する権限を持っていないことを読んでいますか?

この種の問題のベストプラクティスは何ですか?

おかげ

エヴァンの本、ページから

答えて

5

139:

意味「あなたは既存のAGGREGATE内の要素を追加する必要がある場合、あなたはAGGREGATEのルートにファクトリメソッドを作成することがあります」 AbstractElementの詳細を取得するルート(A)にファクトリメソッドを作成する必要があります。このメソッドは、いくつかの決定パラメータに従ってAbstractElement(X/Y/Z)を作成し、それをAbstractElementsの内部コレクションに追加します。最後に、このメソッドは新しい要素のidを返します。

よろしく、

Itzik Saban

+0

私の場合、詳細はエンティティごとに異なります。 Xのインスタンスを作成するには、1つの文字列が必要です。 Yのインスタンスを作成するには、2つの文字列が必要です...この場合、どのように動作しますか?方法は1つしか使用できません。 –

+0

DDDでは、1つのメソッドしか作成できないため、FACTORYメソッドとして機能する限り、3つの異なるメソッドを作成できます。 – ItzikSaban

+0

しかし、この場合、私の質問で提起した問題は依然として存在します。新しい型が追加されるたびに新しいファクトリメソッドを追加する必要があります。 –

2

いくつかのコメント。以前の回答者からは、ファクトリメソッドを使用することをお勧めします。それを避けることができれば、青からオブジェクトを作成しないでください。通常、それはあなたのドメインからより多くの意味を作るためにかなり大きなにおいと逃したチャンスです。

私はこれを説明するための小さな例を書いた。ビデオはこの場合集約ルートです。集合体の境界内には、ビデオオブジェクトとそれに関連するコメントがあります。コメントは匿名でもよいし、既知のユーザーによって書かれたものでもよい(例を簡略化するために、私はユーザー名でユーザーを表していたが、実際のアプリケーションではUserIdのようなものがある)。ここで

はコードです:また、上の熟考する

public class Video { 
    private List<Comment> comments; 

    void addComment(final Comment.Builder builder) { 
     this.comments.add(builder.forVideo(this).build()); 
     // ... 
    } 
} 


abstract public class Comment { 
    private String username; 
    private Video video; 

    public static public class Builder { 
     pubic Builder anonymous() { 
      this.username = null; 
      return this; 
     } 

     pubic Builder fromUser(final String username) { 
      this.username = username; 
      return this; 
     } 

     pubic Builder withMessage(final String message) { 
      this.message = message; 
      return this; 
     } 

     public Builder forVideo(final Video video) { 
      this.video = video; 
      return this; 
     } 

     pubic Comment build() { 
      if (username == null) { 
       return new AnonymousComment(message); 
      } else { 
       return new UserComment(username, message); 
      } 
     } 
    } 
} 

public class AnonymousComment extends Comment { 
    // ... 
} 

static public class UserComment extends Comment { 
    // ...  
} 

ことの一つは、集約境界がオブジェクトではなくクラスを含んでいることです。したがって、特定のクラス(主に値オブジェクトですが、エンティティの場合もあります)が多くの集約で表現される可能性が高くなります。