「エリック・エヴァンスのドメイン駆動設計」感想

[エリック・エヴァンスのドメイン駆動設計](https://www.amazon.co.jp/%E3%82%A8%E3%83%AA%E3%83%83%E3%82%AF%E3%83%BB%E3%82%A8%E3%83%B4%E3%82%A1%E3%83%B3%E3%82%B9%E3%81%AE%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E9%A7%86%E5%8B%95%E8%A8%AD%E8%A8%88-Architects%E2%80%99Archive-%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E9%96%8B%E7%99%BA%E3%81%AE%E5%AE%9F%E8%B7%B5-%E3%82%A8%E3%83%AA%E3%83%83%E3%82%AF%E3%83%BB%E3%82%A8%E3%83%B4%E3%82%A1%E3%83%B3%E3%82%B9/dp/4798121967)

ドメイン駆動設計に関して記載した本を何冊か読んだので、原典を読んでみました。

#書籍の概要
##ドメイン駆動設計(DDD)とは
ドメイン(知識、影響、または活動の領域)に対して、
開発者とドメインエキスパート(開発担当ではない、ドメインに関する深い知識を持っているプロジェクトメンバ)が共同して
ドメインのモデルを作成し、モデルと実装を同期させ、モデルをブラッシュアップし続ける、という設計方法です。

そのために、ドメインに対してユビキタス言語(ドメインのモデルに関連して、全員で使用できる共通の用語、言語)を構築し、
ドメインエキスパートと開発者がユビキタス言語で会話することでモデルをブラッシュアップします。
また、開発者が実装、リファクタリングを進める中で発見した内容をモデルにフィードバックすることでも、モデルをブラッシュアップします。

この、ドメインエキスパートとの共同と、双方向でのモデルのブラッシュアップが重要となります。
また、モデルは進化し続けるものであり、一度作成して完成するものではありません。

##DDDのメリット
モデルと実装が対応した状態を保つことで、
ソフトウェアを進化可能な状態に維持し、
継続的にユーザの要望に応えるための修正を続けていくことで、
ソフトウェア開発が成功した状態(ユーザに利用され、ユーザの問題を解決している状態)を保つことが出来る、
というのがDDDのメリットです。

##値クラス、エンティティ、サービス・・・
DDDについて、入門向けのWebページや書籍を見ると、
値クラス、エンティティ、サービスといったクラスの設計について記載されていることが多いですが、
これらは、DDDの要素としては、さほど本質的ではないです。
これらはDDDのにより作成したモデルを実装に落とす上でのパターン的なものです。
(書籍の記載量も、全体の10%程度であり、繰り返しピックアップされることも無いです)

#感想
##書籍の評価
総じて、読む価値があったと思います。

DDDは、うまく導入できれば有効に機能しそうに思います。
ただ、導入するには結構な努力と現場での啓もうが必要になりそうです。

また、記載されている設計のパターン(レイヤ化、腐敗防止層等)やクラスの設計(値オブジェクト等)は、
DDDとは関係なく役には立ちそうです。

##この書籍の難易度
DDDについて、特にこの書籍については、理解が難しい、という記載をよく見ますが、
読んだ印象としては、さほど難しいとは感じませんでした。
(翻訳本特有の読みづらさはありますが)

記載されているモデリング作業の例について、モデルの細かい意図等は理解が難しいですが、
これはそのドメイン(物流、金融等)についての知識が不足しているためであり、無視して良いと思います。
重要なのは、モデリング作業の進め方と、どういう作業、思考の流れでモデルの改善を行ったかであるためです。

DDDについて学びたいのであれば、一度読んでみるべきと思います。

#DDD導入の難易度は？
悲観的ではありますが、政治的な問題で
日本の多くの現場では、DDDを導入するのは非常に困難、もしくは不可能だと思います。
なぜかというと、DDDは前提として

1. 開発者とドメインエキスパートが共同してモデルとコードをブラッシュアップし続ける
1. モデリングを行う技術的な人は、一定時間をコードに触ることに費やさなければいけない

という二つがあるためです。

まず、1ですが、モデリングと開発を続けることで、ドメインに対する知識を深め、
モデルとコードをブラッシュアップし続けることが必要になります。
(小さなブラッシュアップだけではなく、戦略的に見た大きなブラッシュアップも必要になります)
そうすることで、設計がブレイクスルーに達し、ドメインの本質をより深くとらえたモデルを手にすることが出来るとしています。
ただ、実際には、既にリリース済みのコードを修正することを避ける現場が多く、
ブラッシュアップし続けるのは困難と思われます。

次に2ですが、これが日本の多くの現場で絶望的ではないかと思います。
もし、その現場が

* コードを書くことから卒業した人が設計、モデリングを行い、経験の浅いメンバーが実装を行う
* SIer等の一次受け会社の社員だけがエンドユーザとの接点を持ち、二次受け以降の会社の社員が実装を行う

というような進め方であれば、DDDを導入するのはかなり困難です。
モデリングを行う開発者が実装を行わない状態は
書籍内で、明確にアンチパターンとして記載されています。

このような作業を行っている現場でDDDを導入しようと思うのであれば、まず作業の進め方(や契約形態)を変更する必要が有り、
かなり困難、もしくは不可能だと思います。

以下の様な現場であれば、そういった政治的な問題なしでDDDを導入できそうです。

* 自社サービス、自社製品の開発を行っている現場
* 既にアジャイルなりで、開発者とユーザが対話できている現場

##軽量DDD
DDDで記載されている技術的な要素(値クラス、エンティティ、サービス・・・)のみ導入することを
軽量DDDと呼んで、その是非が議論されているようです。
これは、多くの現場では本格的にDDDを導入するのは困難(もしくは不可能)なため
まずは目の前のコードの改善だけでも行おうということかと思います。

軽量DDDがコード改善に有効か、ということであれば、有効とは思います。
ただ、そもそもこれらの技術要素は、オブジェクト指向を正しく学んで、経験を積んでいけば、
自然と行き着く内容だと思います。
不変クラス、業務ロジックをどこに配置するかの整理、各モジュールが持つ知識のレイヤ化等、
DDDだから行う内容ではなく、オブジェクト指向で開発を行うのであれば、普通のことです。
しかし、多くの現場では、オブジェクト指向に従った、こういった設計、開発すらできておらず、
まずは軽量DDDで技術的な底上げを、という流れになっているのではないかと思います。

#軽量DDDからDDDへ移行できるのか？
DDDでは、必要な技術知識は前提条件となります。
オブジェクト指向は必須ではないのですが、
現状ではオブジェクト指向がDDDを導入するうえで一番有力な選択肢であり、
必要な技術として、開発者が身に着けていることを想定しています。

そのため、軽量DDDでDDDに必要な技術的な底上げを行った後で、
本格的なDDDに移行していく、という流れは成功の可能性があると思います。
いきなりDDDを導入しようとしても、開発スキルが不足していて、
作成したモデリングを正しく実装に落とすことが出来ない、となってしまうよりは、
導入が成功する可能性がありそうです。

ただ、軽量DDDからDDDへの移行は、技術的な問題ではなく、政治的な問題を解決する必要が有り、
これは全く別のハードルだと思います。