ドメイン駆動設計本の読書会に参加してきた

エリック・エヴァンスのDDD本、大阪で読書会が開催されているというので行ってきた。

【限定募集:第1回の申込者のみ、参加登録可能】第2回ドメイン駆動設計読書会@大阪 - ドメイン駆動設計読書会@大阪 | Doorkeeper

勉強会はまだ1章途中、自分で読んだのもまだ4割くらいだけど、得るものが多い本&勉強会だと思う(主催の@kuma_nanaさんありがとうございます)。

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

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

ざっくりに言うと、ドメイン(ユーザーの問題領域)のことを深く考えてソフトウェア作っていきましょうという本。これとこれを実践すればDDDだとか、こういう図を描けばDDDだぞみたいな事よりも、根本にある考え方と、それを実現するためのパターン集といった趣。読む前は○×駆動が世の中沢山あるなあと思っていたけど、TDDとかMDDと相反するものではなくて、むしろ一緒に組み合わせて効果を発揮する感じ。考え方については序文に(たぶん)大事なことが書いてある。

根本的には、DDDを駆動している原則は次の3つだけです。

  • コアドメインに集中すること。
  • ドメインの実践者とソフトウェアの実践者による創造的な共同作業を通じて、モデルを探求すること。
  • 明示的な境界づけられたコンテキストの内部で、ユビキタス言語を語ること。

ドメインに対する知識をモデルに落とし込み、プロジェクトに関わるドメインエキスパート*1やらプログラマやらがモデルを継続的に洗練させていく。モデルや実装、コミュニケーションやドキュメントに使われる用語はすべて統一して(=ユビキタス言語)、誤解が生じないようにする。会話やコードに苦しい面が現れたなら、よりよい表現を探求しなければいけなくて、それはよりよいモデルを探求していることに繋がる。モデルと実装の言葉を強制的にそろえることで、プログラマがみんなモデルのことを考えることを強いられる(?)というのが面白いと感じた。ドメイン層のコードをリファクタリングするのはモデルのリファクタリングに等しいし、逆によりよいモデルを見つけ出したのならコードにも反映させる必要がある。

当たり前のことを当たり前にやる

1章に入る前のところで、コメディ番組の撮影に関するエピソードが出てくる。あるシーンの撮影が上手くいかなくて何度も撮り直し、ようやく面白い映像が撮れたんだけど、画面に一瞬ゴミが映りこんだのを理由に編集者が別の全然面白くないテイクを採用しちゃいましたという話。同じ節で、技術力のある開発者はドメインを学んだりモデリングするのを他人任せにして、複雑なフレームワークに取り組んでみたりコンピュータ科学っぽい問題を解くことに集中したがるという話があった。この辺はドメイン駆動設計をやる/やらない以前の問題で、手段と目的(=ユーザーに価値を届ける)を間違えちゃ駄目でしょという当たり前の話だと感じた。「ドメイン駆動設計を実践する」というと難しい響きだけど、その背後にある「ドメインの事をしっかり考えて仕事する」、というのはソフトウェアに限らず当然やるべき事だろうと思う。

とはいえ本質的に複雑なソフトウェアに立ち向かう時には、当たり前のことを当たり前にやるのがすごく難しい。それを何とかやっつけるための仕組みとしてドメイン駆動設計が提案されているんだろうなというのが今の所の感想。

たとえばウォーターフォールだと、まずアナリストがドメインを分析して分析モデルを作り、後から開発者が設計を行うみたいな事をやる。分析モデルは実装の都合のことを考えないので、開発者から見ると「絵に描いた餅」みたいに見えることがある。結局開発者で別の抽象化を考えてしまったりで、分析モデルに組み込まれていたドメインの知識が失われていってしまう。逆に、実装をしていく中でよりよいモデルが見つかっても、分析モデルに反映されることもない。
(話が逸れるけど、以前モデリングに関する講習を受けて、分析モデルは実装の都合考えてないけどここからどうやって実装するんですかと質問したら、分析モデルは分析したら捨てますって答えが講師から返ってきて驚いたことがある。食材をひたすら煮込みに煮込んでから、出汁の出た煮汁を全部捨てて残りを食うイギリス料理のコピペを反射的に思い出した覚えがある。どうでもいい。)

一方アジャイルっぽいやり方で継続的にリファクタリングしていくにしても、どういうドメインモデルが表現されているのかを無視してコードに手を加えていくと、無駄に複雑になっていってしまう。部分部分を見るとおしゃれに設計されているように見えるんだけど、全体としてどういう価値を届けるソフトウェアなのか分からなくなってしまったり、変更に強いコードを書いているつもりでいて、実際に変更があった時にはなんだか沢山書き変えなきゃいけない、柔軟性を持たせた筈の部分が重荷になっているとかいう事態になりかねないようにも思う。ここらへんを全部プログラマのセンスの問題に帰着させるよりは、ドメインモデルをみんなで磨いていく中で良い設計を見出していくドメイン駆動の考え方のほうがしっくり来る。

設計が、あるいは設計の中心となる部分が、ドメインモデルに紐づいていないならば、そのモデルにほとんど価値はなく、ソフトウェアが正確であるかどうかも疑わしい。同じように、モデルと設計された機能との紐づけが複雑だと理解するのが難しく、実際には設計が変更された時に紐づけを維持できなくなる。分析と設計の間に致命的な亀裂が生じるため、それぞれの作業で得られる洞察は互いに活かされることがないのだ。

どう実践するか

ドメイン駆動設計は考え方っぽい本なので実践が伴わないと「ふーん」で終わる感がとても強い。「理論と実践の両輪が大事」という言葉が読書会の中でも出てきていた。じゃあ自分の組織でどう取り入れていくのか、考えているけどまだ答えは出ていない。新しい考え方○○を取り入れようとした人が、本人の理解も不十分なまま周りを巻き込んだために上手く行かず、「○○はウチでは使えないね」みたいな偏見だけを社内に残したみたいな状態は最悪なので、それは避けたい。最初は500行くらいの規模のコードで小さく実践すれば良いのでは、という話も出てきていたので、まずは小さく始めたいなという感じ。

*1:ユーザーの業務領域に対する知識と判断責任を持つ人。必ずしもユーザーである必要は無いという話が読書会の中でも出ていた