モジュール(Module)(DDD)
エンティティや集約、バリューオブジェクトなどドメインオブジェクトを整理してまとめる存在。それらをまとめる存在なので、モジュールの名前もドメインとして意味のある名前でなければならない。
小難しい話はなく、モジュールとは何か説明すれば以上の通りになる。
ただ、エリック・エヴァンスのドメイン駆動設計 第14章で「境界づけられたコンテキストはモジュールではない」というコラムがあり、コンテキストを分けることとモジュールを分けることは違うというようなことが書かれている。
コラム——境界づけられたコンテキストはモジュールではない
この問題は混同されることもあるが、動機が異なる別々のパターンなのだ。確かに、2つのオブジェクトの集合が別々のモデルを構成していると認識される場合、そうしたオブジェクトはほとんど常に別個のモジュールに置かれることになる。そうすることで、別々の名前空間(異なるコンテキストには不可欠)と何らかの境界が与えられる。
しかし、モジュールは1つのモデルの中で複数の要素を構成するものでもあり、別のコンテキストに対して、必ずしも意図を伝えるものではない。境界づけられたコンテキストの中でモジュールが個別の名前空間を作成することにより、実は、偶発的に発生するモデルの断片化が見つけにくくなっているのだ。
エリック・エヴァンスのドメイン駆動設計 第14章 モデルの整合性を維持する 境界づけられたコンテキスト(BOUNDED CONTEXT)
かなり意味を掴みにくい文章なのだが、コンテキストに対応する他のモジュールとそれを下支えする機能をまとめたモジュールなどを想定しているのかもしれない。
例えば、人事評価モジュールと給与計算モジュールはコンテキストに結びついている。それらを下支えする存在として社員モジュールを作るとすると、そのモジュールは何のコンテキストにも対応しないモジュールになるだろう。
ただ、集約(Aggregate)でも言及するがネットワーク構造になるため避けた方がいいだろう。人事評価における社員と給与計算における社員は異なる責務を持つはずで、1つのモジュールに押し込んでしまうと単一責任の原則に違反する可能性が高い。それぞれのモジュールで社員クラスを用意する方がよい。
また、同じ理由で他のモジュールに対して依存するのは避けた方が良い。強いていえば、入れ子のモジュールで親モジュールにある集約から子モジュールの集約に依存するケースが考えられるが、そういう場合は、親モジュールの集約を新しい子モジュールとして独立させてドメインサービスでふたつの子モジュールの集約を橋渡しするやり方をした方が良い。いくつかのモジュールで使うバリューオブジェクトや仕様がある場合も、第三者のモジュールとして作るのではなく、入れ子モジュールにして親モジュール直下にバリューオブジェクトなどをおく方がよいだろう。
そして、そういったモジュール関係を意識すると結果としては、モジュールはコンテキストを分ける存在になっているはずである。