モデルが息づく場所

"Domain-Driven Design"におけるドメインモデルの性質について簡単にふりかえった上で、そのドメインモデルが位置づけられる領域について整理する。

導入:ドメインモデルとは


DDDにおける主要な主張は、ソフトウェアが対象とする領域(ドメイン)についてのモデリングを正確に行った上で、それをソースコードにおいて表現するというものでした。ドメインモデルとはつまり「ドメインについてのモデル」なのですが、これは実体としてアプリオリに存在するものではなく、「現実を解釈することによって、目の前の問題を解決する上で重要となる側面を抽象化したもの」(p.2)、あるいは「ドメインエキスパートの知識が厳格に組織され、選択的に抽象化されたもの」(p.3)とされてます。つまり、現実世界を写し取ったものではなく、ある特定の視点に基づいて世界を切り取ったものである、ということですね。もちろん、ここで言われているモデルはデザインパターンを駆使して作り上げられたクラス設計でもありません。このことは、Reenskaug氏とCoplien氏がDCIアーキテクチャで述べている「オブジェクトはまず人々とそのメンタルモデルに関するものであり、ポリモルフィズムや結合、凝集に関するものではない」という主張と本質的には同じものであると考えられます。


人間が現実世界を解釈するために用いるものが言葉である以上、ここでモデルを構成するものもやはり「言葉」となります。やや気取った言い方をすれば、ドメインモデルとは「言葉が織りなす解釈された構造」と表現できるかもしれません*1。そういうモデルを構成している言葉をチームで共有しよう、そしてコードを含むあらゆる場所で利用しよう、それがユビキタス言語("Ubiquitous Language")とモデル駆動設計("Model-Driven Design")の構想です。


このことを前提とした上で、「それではそのドメインモデルはどのような領域に位置づけられるのか?」という問いに対する答えをDDD本の中から見いだすことが、この記事の目的です。


レイヤ型アーキテクチャ(Layered Architecture)


DDDは全4部構成となっており、そのうちの第2部には「モデル駆動設計の構成要素」という名称がつけられています。その中に具体的なパターンとして、エンティティ("Entity")や値オブジェクト("Value Object")、サービス("Service")、リポジトリ("Repository")といったものが登場することになるのですが、そういった個別のパターンに先立って提示されるのが、「ドメインを扱う場所をシステムの他の場所から分離しなければならない」という主張です。

The part of the software that specifically solves problems from the domain usually constitutes only a small portion of the entire software system, although its importance is disproportionate to its size. To apply our best thinking, we need to be able to look at the elements of our model and see them as a system. We must not be forced to pick them out of a much larger mix of objects, like trying to identify constellations in the night sky.


ソフトウェアのうちでドメインに起因する問題を解決することに特化した部分は、ソフトウェアシステム全体から見ればごく一部を形成するにすぎません。しかし、この重要性は大きさに比例しません。私たちの考え方を最も正しく適用するには、モデルを形成する諸要素を明確に指差す必要があり、それをシステムとして見る必要があります。オブジェクトの巨大な寄せ集めの中から、夜空に星座を探すように、モデルを拾い出さねばならないというのではまずいのです。(p.67)

このような分離を行うためのパターンが「レイヤ型アーキテクチャ」であり、これは具体的には次の4つの階層から構成されます。

名称 役割
User Interface ユーザに対して情報を表示し、ユーザからの指示を解釈する
Application Layer ソフトウェアのふるまいを定義し、ドメインオブジェクトをキックする
Domain Layer 業務の状況やルールに関する情報を表象する、ソフトウェアの中核
Infrastructure Layer 技術的な機能を高次の層に対して提供する


このようにドメインレイヤを分離することがレイヤ型アーキテクチャの目的です。このドメインレイヤについてEvansは「ドメインレイヤはモデルが息づく場所である("The Domain Layer Is Where the Model Lives")」と題された節において次のようにも語っています。

The domain model is a set of concepts. The "domain layer" is the manifestation of that model and all directly related design elements. The design and implementation of business logic constitute the domain layer. In a MODEL-DRIVEN DESIGN, the software constructs of the domain layer mirror the model concepts.


ドメインモデルとは一連の概念です。「ドメインレイヤ」はそのようなモデルの表明であり、全ては設計の諸要素と直接的に関連づけられます。ビジネスロジックの設計と実装がドメインレイヤを構成します。モデル駆動設計において、ソフトウェアはモデルの諸概念を映し出すものとしてドメインレイヤを構築するのです。(p.75)

このドメインレイヤが、DDDの構成要素("Building Block")とされるエンティティや値オブジェクトが息づく場所になるということです。


境界づけられたコンテキスト(Bounded Context)


レイヤ型アーキテクチャは、単一システムのアーキテクチャ上において、明確にドメインのための場所を作るべきだという主張でした。これは重要なものではありますが、ある程度ソフトウェアアーキテクチャに慣れた人にとっては自然なものと感じられる発想だと思います。それに対して、ここで扱う「境界づけられたコンテキスト」は、ドメインモデルを構築する言葉あるいは概念の有効範囲に関するものです。


第4部「戦略的デザイン("Strategic Design")」のうち、「境界づけられたコンテキスト」パターンの説明では、このようなコンテキストが求められる原因として、巨大なプロジェクトにおいて複数のモデルが機能している場合にコミュニケーション上の混乱が生じることが指摘されます。それを踏まえて、Evansは次のように主張します。

Explicitly define the context within which a model applies. Explicitly set boundaries in terms of team organization, usage within specific parts of the application, and physical manifestations such as code bases and database schemas. Keep the model strictly consistent within these bounds, but don't be distracted or confused by issues outside.


モデルが適用されるコンテキストを明確に定義して下さい。そして、明確に境界を設定して下さい。この境界は、チーム編成、アプリケーションにおける特定部分の利用、コードベースやデータベーススキーマの物理的な宣言といった観点から設定して下さい。こうして設定した境界内においてはモデルの一貫性を厳格に保ち、外部の問題によって妨げられたり混乱させられたりすることがないようにして下さい。(p.336)

ドメインモデルを構成するものが本質的には言葉であったことを考えれば、ここで用いられている「コンテキスト」という表現は比喩的なものではありません。境界づけられたコンテキストの内部で起こりうる混乱の例としては、次の2点が挙げられています。

  • 重複した概念("duplicate concept"):同一の概念を表象するモデル要素が2つある状態
  • 偽同族語("false cognates"):同一の言葉を使って違うものを指している状態

「コンテキスト=文脈」が言葉に意味を与えるように、モデルを構成するある言葉の意味が一意なものとして成立し得る領域を明示的に定めること、これが「境界づけられたコンテキスト」というパターンによって示されていることだと言えます。


まとめ:制限された自由な空間

ドメインエキスパートの言葉に耳を傾けること、共有された言葉で共通のモデルを作り上げること、このモデルを反映させたコードを書くこと、変化に対応するためにモデルを柔軟に保つこと。こういったことはDDDにおける重要なプラクティスですが、あくまでも視野はモデルの構築に限定されています。モデルをより広い全体の中に位置づけることによって、また少し違う姿が見えて来たのではないでしょうか。モデルの一意性、柔軟性は特定の領域を明示的に設定することによって担保されるものでした。この、言わば「制限された自由な空間」こそが、モデルが息づく場所なのです。




Photo Credit



Domain-Driven Design: Tackling Complexity in the Heart of Software

Domain-Driven Design: Tackling Complexity in the Heart of Software

*1:もちろん、Evans自身がこういう詩的(?)な表現をしている訳ではありませんが。