『エリック・エバンスのドメイン駆動設計』読書メモー第3章

最近、更新が滞りがちな本ブログ。
今回は『エリック・エバンスのドメイン駆動設計』の第3章のメモを紹介する。
例によって、不正確、不明瞭なところがあると思うでの、ツッコミをいただけるとすごくありがたい。

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

第3章は、モデル駆動設計を中心として、ソフトウェア開発におけるモデルの扱いに関する知識を扱ってる。

モデル駆動設計とは、その名のとおり、モデルを中心に据えてソフトウェアの設計を行っていゆくことだ。

この際に重要なことは、
「いかに噛み砕かれた知識が反映されたモデルを、ソフトウェアに反映できるか」
だ。

エリック・エバンスは、過度の分業により分析、モデリング、設計、プログラミングの工程を経てゆく際に、モデルがもっているはずの知識が失われることを警告している。

現状のシステム開発では、分析、設計、開発とフェーズが分けられており、なおかつそのフェーズをたんとする人間も分けられている。
たとえば、経験豊かなエンジニアが設計者としてモデルを作成し、そのモデルを見つつ経験の浅いエンジニアがコードとして変換するというように。

もしかしたら、経験豊かは単価の高い、経験の浅いは単価の安い、と読み替えてしまっても良いかもしれない。

こうした分業の問題は、フェーズの直線的な流れを生み出すことだ。
そして、分析→設計→開発と直線的に仕事が流れてゆくことで、各フェーズの仕事がフェーズごとに完結すると信じられていることだ。

むしろ、プロジェクトに少しでも携われば、おおくのソフトウェア開発に携わるエンジニアも各フェーズの成果物が完璧な状態で伝わってくるなどと信じない。
「設計書を疑え」などという言葉は、よく聞く言葉だと思う。

しかし、プロセス自体が「完全な成果物が前の工程から流れてくる」とことを前提にしているのだ。

現実はたとえば、開発時に設計不備が発覚すると、設計まで戻って作業をやり直す必要がある。
これを「手戻り」と呼び、どのようなソフトウェア開発でもなるべくなくしたい、と思われているものだ。

一般に、フェーズが後ろの方にゆけばゆくほど、問題発生時のリカバリーまでのコストは高くなる。
たとえば、分析の問題をそのときに発見し対処した場合と、テストになって発見した場合では、やり直すことが増える。

分析時に気付いておけば、分析の作業だけをやり直せば良いのだが、テストをしているときに発見した場合では、プログラミングも設計も分析もやり直さければならない。

こうした「手戻り」によるコストをなるべく防ぐために、「要件を固めて変更しない」ということも可能だ。
しかし、これは「手戻り」によるコストよりもなお悪い、いらないものをつくる、という結果に陥る可能性がある。
つまり、ソフトウェアまるまるコスト、という状況だ。

そんな事態に陥らないためにも、分析からテストまでを直線的に進めるのではなく、反復させながら進めてゆく方法が取れる良い。
分析から設計、開発、テストを短い期間で反復的に行うことで、要件の変更に対応する可能性が増す。

なによりも、分析時に発覚しなかった問題が、テストの時に発見されても比較的に短い時間で発見できる。
そのため手戻りによるコストも抑えることができる。

手戻りがゼロになるわけでもなければ、不要な機能を作ってしまことがゼロになるわけでもない。

しかしながら、発生した際の影響を小さくすることはできる。

各フェーズを直線的に進めるのではなく、反復させながら進めてゆくことで、分析は、設計や開発、テストの際に発見した問題や新たな知見を取り込むことができる。
つまり、各工程からのフィードバックを頻繁に取り込んでゆくことで、ソフトウェアを洗練させてゆくことができるのだ。

そのため、エリック・エバンスは、分析モデルを否定している。
すなわち、

純粋な分析モデルでは、ドメインを理解するという第一の目標にさえも到達できない。重大な発見はいつでも、設計や実装をするために努力する際に現れるからだ。(p.46)

モデルは単なる分析フェーズにおける成果物として終わらせてはいけない。
ドメインエキスパートとの会話から作成されたモデルは実装のさいに使用され、ソフトウェアのプログラムとして実現するのだ。

モデル駆動設計

モデル駆動設計は、分析モデルと設計という二分法を捨て去り、両方の目的に使える単一のモデルを探し出す。純粋に技術的な問題をさておき、設計にあるオブジェクトはそれぞれモデルで記述されている概念的な役割を果たすことになる。(p.47)

モデルを中心に設計を行うということは、分析、設計を分けて考えない、ということだ。
エリック・エバンスは、ほとんど例外なく、1つのプロジェクトには1つのモデル(1つの図ではない)を使用することを推奨している。

両方の目的を果たすということから、そのモデルは頻繁に変更されることを前提としている。
そのため、メンテナンスのコストが比較的大きことも認めているようだ。

実プロジェクトになると、メンテンスという作業はおざなりになりがちだ。
というのも、作って動けば格好はつくけれども、作れませんでした、では格好がつかないからだ。

そのため、どのようなフェーズにあっても作業をすすめることへの動機はあっても、作業の手を止めて情報共有や資料作成や修正へを行う動機は薄い。
また、メンテナンスの重要性は分かりつつも、なるべく簡単にメンテナンスしようとするあまり、何の訳にも立たない資料が作ってしまうこともある。

モデル駆動設計においては、分析のみならず設計や開発の知見を取り込み豊かなモデルが作成されることが重要だ。
そのため、優れたモデルが常に維持するためのコストは支払うことをしっかりと認めないといけない。

「ちゃんとメンテナンスしよう」という言葉は、文章で読めばスジが通っていて、共感するばかりの言葉だ。
でも、実施のプロジェクトにおいては、ついつい作業だけを先行させてしまって、モデルを作り込むことが疎かになりがちだ。

オブジェクト指向の有用性

モデル駆動設計を成功させるには、モデルと設計は文字通りに対応し、人が綴り間違えを犯さない限り正確でなければならない。モデルと設計をそのように厳密に一致させる上でほぼ必須となるのは、作業に用いるモデリングパラダイムが、モデルに含まれる概念と直接的に類似したものを生成できるソフトウェアツールによってサポートされるということだ。(p.48)

このあとに、オブジェクト指向モデリングパラダイムに基づいて、モデルの概念に実装を提供するために強力なツールであると、エリック・エバンスはいう。

僕自身、オブジェクト指向の有用性についてあまり考えてことがない。
というのも、実際のプロジェクトではどうあれ、現在のパラダイムオブジェクト指向である、という認識があったからだ。
それは刷り込みのようなもので、ある種、盲目的にオブジェクト指向の有用性を信じきっていた。

というのは、汎用機の開発で手続き型のつくる簡単さとメンテナンスの大変さを経験していたため、隣の芝生は青くみえていたからだと思う。

今回のエリック・エバンスの指摘で、「なぜ、オブジェクト指向か」ということにはっきりとした理由がついたと思っている。
作成されたモデルの概念は、分析モデルのように分析にしか使えないものではない。

開発においても使用できるモデルだ。

そのため、たしかに理想的な(絵に描いた餅の)モデルが現実の実装では変更されてしまうこともある。

その場合は、コードとともにモデルが変更される。
コードの変更が設計に簡単に反映できるのは、まさにオブジェクト指向による恩恵だ。

コードがモデルの概念を反映して作成されることで、コードの変更が行われときには、モデルのどの部分を修正すればよいか、がわかりやすくなる。

オブジェクト指向といえば、「再利用」という判を押すようなイメージがある。
しかし、もうひとつの強みとして分析し設計を通じて、洗練させたモデルの概念をコードに反映できるという強みも覚えておきたい。

実践的モデラ

ソフトウェア開発は、すべてが設計なのだ。(p.57)

そのため、モデラはコードを書くことが望ましい。
上記した、過度な分業によって当初モデルが持っていた知識がどんどん流出してしまう。

たとえば、モデラからモデルを開発者に引き継ぐときに、大切な事が全て伝えられることはない。
また、開発時の発見によるフィードバックがえらない。
このため、モデルが貧弱になってしまう。

現実でも優秀な人が設計し、そうでもない人が設計書を見つめてコードを書く、という体制でプロジェクトがすすめられることが多い。
開発者がたいしたことのない人だった場合、「設計者はどうしてこんな設計にしたのか」ということには気づかないかもしれない。

そのため、プログラムを動かすために、重要な部分を排除してしまうかもしれない。

僕自身、将来的にはソフトウェアを設計できるようになりたいと思っている。
一方で、開発の経験が足りないと思っている。
だからこそ、優秀な設計者になれるとは思っていない。

開発経験を積み、ドメインエキスパートとの話し合いから創り上げられたモデルを実現できるような、プログラミング能力を身につけたいと思っている。
なぜなら、実践的モデラであるためには、ドメインモデルや自分の意識を実現化するためのお手本が示せるようになりたい思っているからだ。

まだまだ、プログラミングの経験が不足している。