読書メモ：『エリック・エヴァンスのドメイン駆動設計』


『エリック・エヴァンスのドメイン駆動設計』を読んだので、その内容と考えたことなどをまとめる。
読むのは３回目で、ようやく少しわかってきた。

## この本で書かれていること

「いかにしてソフトウェア開発を成功させるか」ということ。もっというと、この本のサブタイトルにあるとおり、いかにして「ソフトウェアの核心にある複雑さに立ち向かう」かということ。その手段として、「ドメイン駆動設計」が提唱される。

ドメイン駆動設計とはどのようなものか。「まえがき」で次のように書かれている。

> 先進的なソフトウェア設計者は、少なくともここ20年の間、ドメインモデリングと設計が重大なテーマであると認識してきた。しかし、何をする必要があって、それをどのようにすべきかについては、おどろくほどわずかしか書かれていない。（中略）ある哲学が出現してきている。私はその哲学を、ドメイン駆動設計と呼んでいる。

ここにあるとおり、「ドメインモデリング」と「設計」にフォーカスし、ソフトウェア開発を成功させるための哲学がドメイン駆動設計（DDD）である。更に、同じく「まえがき」で次のようにも書かれている。

> 本書が提供するのは、設計上の意思決定を行うためのフレームワークと、ドメイン設計について議論するための技術的な語彙である。これは、広く受け入れられているベストプラクティスを、私自身の洞察や経験と統合したものだ。複雑なドメインに直面しているソフトウェア開発チームは、このフレームワークを使用して、ドメイン駆動設計に体系的に取り組めるだろう。

つまりこの本は、DDDという哲学のもと、実際に開発者が何をすべきかについて答えてくれるのだ。

## ドメイン駆動設計の原則

ドメイン駆動設計（DDD）の原則について、「日本語版への序文」からの引用する。

> 根本的には、DDDを駆動している原則は次の３つだけです。
・コアドメインに集中すること
・ドメインの実践者とソフトウェアの実践者による創造的な共同作業を通じて、モデルを探求すること
・明示的な境界づけられたコンテキストの内部で、ユビキタス言語を語ること

「コアドメイン」、「明示的な境界づけられたコンテキスト」、「ユビキタス言語」という耳慣れない単語がでてきたが、これらが「ドメイン設計について議論するための技術的な語彙」となる。

この本全体を通して、上記の原則に沿った解説されていく。

## 3つの原則について考える
ここからは、先ほど引用した３つの原則について考える

### 原則１：コアドメインに集中する

まずは言葉の定義を確認する。以下は、「用語解説」からの引用である。

> コアドメイン：モデルの特徴を示す部分。ユーザの目標の中心となり、アプリケーションを差別化して価値あるものにする。

> モデル：ドメインにおける選択された側面を記述し、そのドメインに関連した問題を解決するのに使用できる抽象の体系。

> ドメイン：知識、影響、または活動の領域。

ドメインの中でも、アプリケーションの価値の本質となるような、より重要なものとして扱うべき部分がコアドメインである。ドメインの中からどのようにコアドメインを選び出し、どのような開発者がこの部分に取り組むかは、「第15章　蒸留」で説明されている。

「ドメイン」について、少し補足すべきだろう。

ドメインとは、開発対象となっているソフトウェアを適用させる領域のことである。この本での例をそのまま使うと、航空会社の予約プログラムのドメインは、実際の後期に搭乗する現実の人々を含み、会計プログラムのドメインは金銭と財務である。

有用なソフトウェアを開発するには、当然のことながらドメインを深く理解しなければならない。ドメインを理解し、それを抽象化しモデルにすることで（モデリング）で、プログラムとして実装可能になる。

しかし、技術的に優れたエンジニアはドメインよりも技術的な課題解決に関心をもつ傾向があり、その結果ドメインの理解が進まず、モデルが貧弱になり、結果としてソフトウェア開発が失敗する、といった例もこの本で示されている。

大規模なシステムでは、ドメインも広範囲に及び、作成されるモデルも同じく巨大なものになる。時間的な制約、人的リソースの制約（優秀な技術者は少ない）などから、すべての部分を同じように取り扱うのは適切でない。

そこで、アプリケーションにとって最も価値ある部分をコアドメインとして選択し、そこに集中して取り込むことが重要だ。

### 原則２：ドメインの実践者とソフトウェアの実践者による創造的な共同作業を通じて、モデルを探求すること

この本で登場する、モデルの探求プロセスを説明するケーススタディにおいて、2つの立場（役割）が登場する。「開発者」と「ドメインエキスパート」だ。

原則の「ドメイン実践者」と「ソフトウェア実践者」は、それぞれ「ドメインエキスパート」と「開発者」のことだと思われる。

開発者は、プログラミング言語やオブジェクト指向などの設計テクニックを使い、ソフトウェアを実装する立場である。UMLやモデリングの知識も持つ。それに対して、ドメインエキスパートは、ドメイン（開発するアプリケーションの領域）についての深い知識をもつ。

ドメインエキスパートは、次のように定義されている。

> ソフトウェアプロジェクトのメンバで、ソフトウェア開発ではなく、アプリケーションのドメインの担当者。ソフトウェアの単なるユーザと違い、ドメインエキスパートはその対象に関する深い知識を持っている。（P.519）

この原則のポイントは、「共同作業」というところにある。

ウォーターフォールのような開発体制では、まずドメインエキスパートによって、ドメインを表すモデルが構築される。そして、このドメインモデルをもとに開発者がソフトウェアの設計を行い、それにもとづいて実装されていく。

ここでの問題点は、ドメインモデルと設計が分断されている点にある。これでは、どちらかの変更にどちらかが追随することが難しく、いずれその紐付けが失われてしまう。

DDDはアジャイルのようなイテレーティブな開発を前提とする。ドメインエキスパートと開発者が協力して、一つのモデルを作り上げ、それは常に見直される。モデルが変われば設計（クラス設計など）が変わるし、反対に設計のぎこちなさからモデルが修正されることもある。

このようにモデルを中心とした開発は、「モデル駆動設計」というパターンとしてこの本では登場する。

### 原則３：明示的な境界づけられたコンテキストの内部で、ユビキタス言語を語ること

後半の「ユビキタス言語」の部分から見ていく。この定義は次のようになされる。

> ドメインモデルを取り巻いて構築され、チームのあらゆる活動をソフトウェアと結びつけるために、チームメンバ全員によって使用される言語。（P.520）

「チームメンバ全員」に、開発者だけでなく、ドメインエキスパートも含まれる点が重要である。2つ目の原則では、ドメインエキスパートと開発者が共同でモデルを探求することが重要であるとしていたが、共通言語がベースとなる。この共通言語はモデル内の用語と一致していなければならない。

図やドキュメント、会話において共通で同一の言語を使う。ソースコードにあらわれる用語（クラス名、メソッド名）についても同様である。

「明示的に境界づけられたコンテキスト」とは、第14章で登場するパターンである。巨大なプロジェクトにおいては、単一のモデルでソフトウェア全体を網羅することは難しい。そこで、プロジェクトをいくつかのコンテキストに分割し、その内部でモデルの一貫性を保つ。

たとえば、貨物輸送のソフトウェアであれば、配送、輸送、請求といったような分け方が考えられる。（P.438）

どのようにコンテキストを分けるべきかも解説されているが、ここでは割愛する。

## 感想

DDDは難しい。

まず、ドメインモデリングが難しい。ドメインエキスパートと蜜にコミュニケーションをとり、ドメインの知識を噛み砕き、それを抽象化しモデルに落とし込む作業が必要だが、この方法はどうやって身につければいいのだろうか。それをソフトウェアの設計およびソースコードと一致させるのもハードルが高い。モデルを発展させていくためには、チームにドメインエキスパートが必要だが、このようなチーム体制は現実的に可能だろうか。アジャイル、イテレーティブな開発プロセスの導入と運用にも難しさがある。しかし、これらをチーム全体、プロジェクト全体で取り組む必要がある。

しかし、この本で書かれたことすべてを適用しなくても、部分的に適用可能で有用なパターンも多く紹介されていた。（たとえば、レイヤ化アーキテクチャ（P.66）は有名である。）

この本でDDDの概要を捉えつつ、取り入れられるパターンを身近な開発に取り入れていくのが現実的と感じた。