DDDを読みながら、「大きなプロジェクトでは、モデルや共通言語を共有するなんて難しいんじゃないだろうか」という、浅い考えを持っていました。*1しかしながらEvansさんは、そんな単純な疑問については、ちゃんと第14章で回答を準備していたのでした。しかも、いくつも。
Domain Driven Designの第14章「Maintaining Model Integrity」は、モデルの整合性について記述した章。システムのモデルとしては、完全に整合性の取れたモデルが1つ存在するのが望ましい。しかしながら、システムの複雑さ、組織体制、プロジェクトにおける政治的な理由などから、大きなプロジェクトでは、各チームごとに、複数のモデルが作られるのが一般的。そのようなモデル間の整合性の保ち方を、以下の各パターンを使って説明している。
BOUNDED CONCEXT
システムにおける各モデルの境界を、明確に定義することの必要性について言及している。BOUNDED CONTEXTによって、そのモデルがシステムのどの範囲に適用されるかという線が引かれる。
CONTINUOUS INTEGRATION
モデルの境界が明確になったら、その境界内のモデルを健全に保っていかなければならない。そのために、テストの自動化、自動ビルドなどによるContinuous Integrationが有効。継続的インテグレーションとして有名ですね。
CONTEXT MAP
各モデル間の関係を表したマップ。システム全体を俯瞰するために必要。
SHARED KERNEL
システムのコアとなるモデルを、複数のモデル(チーム)間で共有するパターン。当然ながら、複数のモデル間で共有されるコード、DBスキーマなどの扱いについては注意が必要。SHARED KERNEL部分を修正する場合は、各チーム間で充分に話し合わなければならない。
CUSTOMER/SUPPLIER DEVELOPMENT TEAMS
モデル間の処理の流れに着目し、処理の下流となるモデル(チーム)がカスタマー、上流となるモデル(チーム)をサプライヤーと定義する方法。サプライヤーはカスタマーの要件を満たすようにインターフェースを定義しなければならない。つまり、下流チームをお客様として扱う。
CONFORMIST
CUSTOMER/SUPPLIER DEVELOPMENT TEAMSとは逆に、下流のモデル(チーム)が、上流のモデル(チーム)にモデルを適合させるやり方。組織の力関係などによっては、この方法をとらざるを得ない場合も多いですね。
ANTICORRUPTION LAYER
モデルの境界に、モデル間の「通訳」を行わせるレイヤーを準備する方法。外部とのやり取りはこのレイヤーを通じて行うことで、各モデルへの影響を最小限にする。レイヤーをワンクッション入れることで、モデルの差異を吸収するやり方。
SEPARATE WAYS
モデル間に重要な関係がほとんど無い場合、各モデルを独立させてしまうというやり方。極論すると、相手のモデルを無視し、独立独歩で開発を進めていく方法。過去の日記で言及した「分割統治」は、このイメージにちょっと近い。
OPEN HOST SERVICE
多くのシステムから利用されるサブシステムについて、そのサブシステムの機能を「サービス」として提供する方法。すべてのシステムに対する「通訳」レイヤーを準備するのに比べ、変更に対して柔軟に対応することが可能となる。
PUBLISHED LANGUAGE
モデル間のデータ交換などのために、そのドメインの本質をよく定義した共通言語を使用する方法。
ちなみに、DDDのパターン一覧がここにコンパクトにまとめられています。とっても便利。