6

私は今これについて議論しており、まだ結論に至っていません。 私が見ているほとんどの例では、アプリケーション層に工場コードがありますが、私はそれがドメイン層にあるべきだと思う傾向があります。 理由: 時々、オブジェクトのすべての作成を通過させたい私の工場で初期検証が行われることがあります。 このコードをオブジェクトのすべてのインスタンスで使用します。 場合によっては、コンストラクタに渡すのが不自然に感じられるパラメータ情報が必要になることがあります。 さらにいくつか重要な理由ではありません。ファクトリーパターンDDDにはどのような場所がありますか?

これは悪い習慣である理由はありますか? これは他のパターンを破りますか?

答えて

4

+1です。アクセシビリティは正当な理由になります。私は創造的なコードを少なくともドメインモデルレイヤーの近くに保ちます。さもなければ、ドメインモデルのユーザは、制限されたアクセスコンストラクタを見つけたときにそれを具体的にインスタンス化する方法を単に混乱させます。実際にそれを分離する1つの理由は、同じものを作成するための異なる有効な方法があることです。抽象ファクトリを使用する場合は通常そうです。

私はそれを分けなければならなかった場合、私はそれを例えば少なくともドメインモデルの同じレベルのパッケージ(Javaの場合)。

upper 
    --> domain 
    --> domain_factory 
+0

ほとんどの人がドメインモデルに参加しているようです。それで、あなたの工場はドメイン層にどこに存在することをお勧めしますか?別のアセンブリ、フォルダ、名前空間? – retslig

4

Eric Evansの書籍には、オブジェクトファクトリがドメインレイヤの大部分を占める例があります。

私にとっては、あなたの工場をここに配置するのが理にかなっています。

7

DDDの工場はfactory patternのインスタンスに過ぎません。そのため、最も理にかなっている場所で使用する必要があります。考慮すべきもう1つの原則は、情報が最も近いクラスに振る舞いを割り当てるべきであることを本質的に述べているパターンです(information expert)。したがって、いくつかのドメイン固有のルールとロジックを適用したい場合は、ファクトリをドメインレイヤーに配置します。結局、ファクトリはドメインオブジェクトを作成します。ただし、他のレイヤには他のタイプのファクトリがある場合があります。

0

ビルダー/ファクトリがドメインクラスとプリミティブに依存する場合は、ドメインレイヤーに配置します。そうでない場合は、ドメインレイヤーの外側に配置します。

0

私はアプリケーション層のファクトを優先します。

あなたがドメイン・レイヤーで工場を続ける場合は、パラメータ(C#のコード例)などの複雑な型を必要とするとき、彼らはあなたを助けにはなりません。

Application Layer: 

//this Factory resides in the Domain Layer and cannot reference anything else outside it 
Person person = PersonAggregateFactory.CreateDeepAndLargeAggregate(
      string name, string code, string streetName,... 
      and lots of other parameters...); 

//these ones reside in Application Layer, thus can be much more simple and readable: 
Person person = PersonAggregateFactory.CreateDeepAndLargeAggregate(CreatePersonCommand); 
Person person = PersonAggregateFactory.CreateDeepAndLargeAggregate(PersonDTO); 



Domain Layer: 

public class Person : Entity<Person> 
{ 
    public Address Address {get;private set;} 
    public Account Account {get;private set;} 
    public Contact Contact {get;private set;} 
    public string Name {get;private set;} 

    public Person(string name, Address address,Account account, Contact contact) 
    { 
     //some validations & assigning values... 
     this.Address = address; 
     //and so on... 

    } 

} 

public class Address:Entity<Address>{ 
    public string Code {get;private set;} 
    public string StreetName {get;private set;} 
    public int Number {get;private set;} 
    public string Complement {get;private set;} 
    public Address(string code, string streetName, int number, string complement?) 
    { 
     //some validations & assigning values... 
     code = code; 
    } 

} 

public class Account:Entity<Account>{ 
    public int Number {get;private set;} 

    public Account(int number) 
    { 
     //some validations & assigning values... 
     this.Number = number; 
    } 

} 

//yout get the idea: 
//public class Contact... 

また、内部の工場を維持するには何の義務はありません(Domain Driven Design Quicklyから)ドメイン層:したがって

、別のオブジェクトに複雑 オブジェクトと集計のインスタンスを作成するための責任をシフト、自体が ない再を有していてもよいですドメインモデルでのスポンサシティーは、まだ ドメインデザインの一部です。すべての複合 アセンブリをカプセル化し、クライアントがインスタンス化されるオブジェクトの具象クラスを参照する必要のないインターフェイスを提供します。 全体を1単位として作成し、不変量を適用します。

私は、永続オブジェクトをメモリに読み込むためにファクトリを使用しないため、アプリケーションのものよりも他のレイヤからアクセスする必要はありません。ここでは、なぜ(Domain Driven Design Quicklyから)です:

別の観察は、工場が最初から新しいオブジェクト を作成する必要があるということである、またはそれらは 以前に存在し、おそらく データベースに永続化されたオブジェクトを再構成するために必要とされています。 エンティティをデータベース内の残りの 場所からメモリに戻すと、 という新しいプロセスが作成されます。が新しく作成されます。明らかな違いの1つは、新しい オブジェクトに新しいIDが必要ないことです。オブジェクトには既に1つあります。 不変量の違反は、異なる方法で処理されます。 新しい オブジェクトが最初から作成されると、不変量の違反はすべて を例外として終了します。私たちは データベースから再作成されたオブジェクトではそれを行うことはできません。オブジェクトは何とか修復する必要がありますので、 は機能する可能性があります。それ以外の場合はデータが失われます。

関連する問題