DI コンテナと Factory パターンについて
モチベーション
DDD っぽい設計を実践してみたいなと考えており、下記を参考に実装を進めていこうと考えていた。
ただ、上記のボイラープレートでは DI コンテナが利用されていた。DI コンテナは実装する側としてはとても楽なのだけど、後から読む側としては一見分かりにくいことも多いし、具体的にオブジェクトに注入される依存がなんなのか追うのが大変だったりするイメージ (そこは実装者がちゃんと実装しろ、ということなのかもしれないが...)。
インスタンス生成のルールを切り出すなら、Factory パターンとして別に置いておく方が分かりやすいような気がして、DDD 的にはそれは (レイヤー的に) どこに位置するのだろうと思った。
今回参考にしているボイラープレートでは、IoC のために各層で以下のような依存性注入を行なっている。
table:DI
層 注入内容
インフラストラクチャ ORM インスタンスを Repository に注入
アプリケーション Repository を Operation に注入
インターフェース Operation を Controller に注入
背景
そもそも作ろうとしていたのは DB を裏にすえた Lambda 上で動作する簡易的な API サーバなので、DDD で設計するほどのものなのか?という問題もある。ただ、簡易的な API サーバと言いつつも、裏にある DB は別の案件でスキーマが変更される恐れがあったし、生やす API の要件も定まっておらず、開発は長期的に改善を繰り返していくことが見込まれたので、場当たり的な設計はよくないと考えた。また、もしかすると全体的なアーキテクチャも変更になるかもしれず、そういったときに ORM に依存した部分がインフラストラクチャ層に切り出されていたりすると便利だ。
別に Factory パターンなんて使いたければ使えば良いのかもしれなのだけど、DDD 的な考え方にそうとどうなのだろうという部分で気になったので調べている (中途半端に導入すると混乱を招きそうなので、せめて何か従うべき方針を見出したい)。
DDD で目指したい部分の1つは関心事の分離のはずで、では Repository の生成 (どの Repository にどの ORM インスタンスを注入するか) に関する事はどこにあるのが自然なのだろうか。そもそも ORM インスタンスも Repository もインフラストラクチャ層内に位置する。
DDD における Factory パターン
Factory パターンは エリック・エヴァンスのドメイン駆動設計 でも紹介されている (p. 134-)。ただ、そこでは主にドメインオブジェクト (値オブジェクトもしくはエンティティ) の生成に利用されている。一方、Repository パターンはオブジェクトの生成後の永続化に利用される。各々、オブジェクトのライフサイクル内で関わる場所が異なる。Repository パターンが自身が扱うドメインオブジェクトの生成を Factory パターンに移譲し、クライアントは Repository パターンを介してドメインオブジェクトを扱う、という例が紹介されている。 その他
実践ドメイン駆動設計 作者のヴァーノン氏のサンプルプロジェクトが GitHub に公開されている。