ファクトリ その1
オブジェクトは蒸留して、その意味に関係しないものや相互作用において果たす役割をサポートしないものが一切残らないようにしなければならない。
複雑なオブジェクトに、それ自体を生成する責務を負わせると、問題が生じる。(第二部第六章より)
そのままですね。ドメインにおいて、意味を持たないオブジェクトや集約の生成・組み立てはファクトリに任せる。
ドメイン駆動設計で、オブジェクトを設計すると、エンティティやバリューオブジェクトでクラスがいっぱいになります。
これらの生成を集約のルートやオブジェクトのコンストラクタでやってしまうと、本来の集約やオブジェクトの仕事に余計な責務を負うことになります。それを分離するということですね。
どこにファクトリを置くか
重要なのは、ファクトリの設計を掘り下げることではなく、ドメイン設計における重要なコンポーネントとして、ファクトリの居場所を示すことである。(第二部第六章より)
どこにファクトリを置くかが、つまり、集約やオブジェクトを誰が生成するのかということが、重要なビジネスの関心事になるということですね
1. 集約のルート
例えば、既存の集約に要素を追加する場合などに適用できる。
DDD本の例では、"購入注文"(集約)が複数の"購入品目"を持っていて、さらに"購入品目"を追加する場合は、"購入注文"が追加分の"購入品目"を生成するということです。
2. 他のオブジェクトの生成に密接に関わるオブジェクト
DDD本の例では、"証券取引口座"が"取引注文"を生成しています。
注意点としては、"証券取引口座"が生成した"取引注文"を持つわけではなく、生成するのに適したオブジェクトだから生成する責務だけを持っているということですね。
3. 専用のファクトリオブジェクトかサービスを作成
自然な置き場所がない場合はためらわず専用のファクトリオブジェクトを作りましょう。通常は集約全体を生成します。
4. コンストラクタでいい場合
構築が複雑ではなく、かつ、オブジェクトを使用する側が実装に関心がある場合。
コンストラクタ内では、他のクラスのコンストラクタを呼び出すのは避けることとあります。そこまで複雑ならばコンストラクタがそぐわないということですね。
4のケースはあまりない気がしますね。なので、基本は1〜3になるかと思います。
明日につづく。