11

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

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

4

5 に答える 5

10

DDDのファクトリは、ファクトリパターンの単なるインスタンスであるため、最も意味のある場所で使用する必要があります。考慮すべきもう1つの原則は、情報に最も近いクラスに動作を割り当てる必要があることを本質的に示す情報エキスパートパターンです。したがって、適用したいドメイン固有のルールとロジックがある場合は、ファクトリをドメインレイヤーに配置します。結局、ファクトリはドメインオブジェクトを作成します。ただし、他のレイヤーに他のタイプのファクトリがある場合があることに注意してください。

于 2012-12-10T16:30:59.220 に答える
8

記憶から、Eric Evansの本には、オブジェクトファクトリがドメイン層の大部分を占める例があります。

私にとって、ここにあなたの工場を見つけることは完全に理にかなっています。

于 2012-12-10T16:25:04.397 に答える
7

それを行うための+1。アクセシビリティは正当な理由です。私は作成コードを少なくともドメインモデルレイヤーの近くに置いておきます。そうしないと、ドメインモデルのユーザーは、アクセスが制限されたコンストラクターを見つけるときに、ドメインモデルを特別にインスタンス化する方法を単純に混乱させることになります。実際に分離する1つの確かな理由は、同じものを作成するためのさまざまな有効な方法があることです。たとえば、AbstractFactoryを使用する場合は通常そうです。

分離する必要がある場合は、たとえばパッケージ(Javaの場合)に少なくとも同じレベルのドメインモデルを入れて、常に一緒に出荷します。

upper
  --> domain
  --> domain_factory
于 2012-12-10T16:33:06.160 に答える
4

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

ファクトリをドメインレイヤーに保持している場合、パラメータとして複雑な型が必要な場合は役に立ちません(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...

また、ファクトリーをドメインレイヤー内に保持する義務はありません(ドメイン駆動設計から):

したがって、複雑なオブジェクトとアグリゲートのインスタンスを作成する責任を別のオブジェクトに移します。このオブジェクト自体はドメインモデルでは責任を負わない場合がありますが、それでもドメイン設計の一部です。すべての複雑なアセンブリをカプセル化し、インスタンス化されるオブジェクトの具象クラスをクライアントが参照する必要がないインターフェイスを提供します。アグリゲート全体を1つのユニットとして作成し、それらの不変条件を適用します。

永続化されたオブジェクトをメモリにロードするためにファクトリを使用しないため、アプリケーション以外のレイヤーからアクセスできる必要はありません。理由は次のとおりです(ドメイン駆動設計からすばやく):

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

于 2015-09-21T15:21:18.367 に答える
0

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

于 2014-02-06T15:51:54.203 に答える