思考と現場の間で

「いいサービスづくり」のために、組織づくりやソフトウェア設計など、考えていることを書きます

【DDDメモ】モデルの整合を維持する

境界づけられたコンテキスト

エリック・エヴァンスドメイン駆動設計 P.344

 複数のモデルはどんな巨大なプロジェクトにも存在する。だが、別々のモデルに基づくコードが組み合わされると、ソフトウェアは、バグの温床となり、信頼できなくなり、理解しにくくなる。メンバー間のコミュニケーションは混乱し始める。あるモデルをどのコンテキストで適用すべきでないのかについては、ほとんどの場合不明瞭である。

【中略】

 モデルが適用されるコンテキストを明示的に定義すること。明示的な協会は、チーム編成、そのアプリケーションに特有の部分が持つ用途、コードベースやデータベーススキーマなどの物理的な表現などの観点から設定すること。その教会内では、モデルを厳密に一貫性のあるものに保つこと。ただし、協会の外部の問題によって注意を逸らされたり、混乱させられたりするのを避けること。

 境界づけられたコンテキストは、特定のモデルが適用出来る範囲を制限する。そうすることで、チームメンバーは、何が一貫性を持つべきで、それを他のコンテキストとどう関係づけるかということについて、明確な理解を共有できるようになる。そのコンテキスト内では、モデルを論理的に統一された状態に保つこと。ただし、その境界の外に対して適用できるかどうかは気にする必要がない。他のコンテキストでは他のモデルが適用されるが、そのモデルとは用語法や概念とルール、ユビキタス言語の方言が異なっている。

 自分自身もやってしまったのは、コンテキストの境界がチームや組織が違う状態にもかかわらず、それを共通化することや関連を持つように考えてしまった。そうすると、関連がカオスになり、もし複数チーム数十人で開発を行った場合、一貫性が保てなくなる可能性が出てきてしまう。そういう意味で、境界を明確に分け、境界内での一貫性を保つ、境界同士ではユビキタス言語の方言が異なる可能性も含めて、明快になる。

エリック・エヴァンスドメイン駆動設計 P.346

 さらに別のチームが、貨物船の運行スケジュールを立てるためのモデルとアプリケーションに取り組んでいる。スケジュール担当チームと予約担当チームは一緒に作業を始め、両チームとも単一の統一されたシステムを作り出すつもりでいた。この両チームは形式張らずに調整し合い、たまにオブジェクトを共有することもあるが、その方法を体系化してはいない。この2つのチームは同じ境界づけられたコンテキスト内で仕事をしているわけではないのだ。これが危険なのは、自分たちが別々のモデルに取り組んでいることに、彼れが気づいていないからである。

 こういうことはありえる。明確に分ける理由は、形でその違いを表明できるからだ。そういう意味で、どちらにしろ曖昧にするのはデメリットが大きいし、曖昧せざるを得ない理由があるのであれば、ある程度明確なプロセスでそのデメリットを補完する必要がある。

エリック・エヴァンスドメイン駆動設計 P.347

 別々のモデルの要素を組み合わせると、2種類の問題が生じる。それが、重複した概念と偽同族語だ。概念の重複とは、実際は同じ概念を表しているモデル要素(およびそれに付随する実装)が2つあるということだ。その情報が変更されるたびに、2ヶ所で変換を伴う変更が必要になる。新しい知識によって、オブジェクトの1つが変更されるたびに、もう一方も分析をやり直して変更しなければならない。ただし、実際には分析がやり直されることはないので、結果として同じ概念の2つのバージョンが作られ、別々のルールに従い、データまで異なることもある。その上、チームメンバーは、同じ事を実行する方法を、1つだけでなく2つ学ばなければならず、しかもしれをずっと同期させておかなければならないのだ。
 偽同族語は【中略】2人の人が同じ用語(または実装されたオブジェクト)を使って、同じ事を話しているつもりでいるのに、実はそうでないというものである。

 これがはっきりと境界づけることのデメリットだ。別々にすることでモデルが明確になるし、チームが考える範囲も小さくて済むが、その分境界ごとの乖離が現れる。その際は、リファクタリングをしたりチームを再編したりする必要があると思うが、境界づけられたコンテキストを徹底する場合は、その辺のバランスを早く察知できるようなプロセスやチーム構成が必要になるのではないか。