ドメイン駆動設計との出会い
10年前に、エヴァンスのドメイン駆動設計を初めて読んだ時は、書いてある内容がほとんど理解できなかった。 あまり、面白いとも思わなかった。
当時は、現場でバグだらけのコードと格闘していた。障害が報告されるたびに、リファクタリング本を参考に、該当個所の長いメソッドや大きなクラスを片端からリファクタリング。その結果、コードがわかりやすくなり、やっかいなバグが単純な修正で解消できてしまうことの効果に驚き、設計の重要性を再認識していた。
それ以前は、UNIXとC言語、OracleとPL/SQLという、オブジェクト指向ではない世界で技術を身に着けてきた。 どちらかというとオブジェクト指向には、ネガティブな印象を持っていた。現場では役に立たんだろうと。
バグとの格闘の中で、リファクタリング(設計改善)の威力を肌で感じ、その考え方とやり方がオブジェクト指向に由来するということを知るにつけ、オブジェクト指向も食わず嫌いではなくもう少し学んでみようと思った。
ワーフスブラックの「オブジェクトデザイン」とバートランドメイヤーの「オブジェクト指向入門」を買い込んで読み始めてみた。 両方とも面白いと思うところもあったが、何を書いてあるのか、よくわからないところも多かった。
実践的なオブジェクト指向との出会い
大きな転換点は、ケントベックの「実装パターン」を読んでから。 オブジェクト指向とは何か、という説明ではなく、「変更の影響の局所化」「コードの重複の除去」「ロジックとデータの一体化」「宣言型の表現」などの設計原則を、なぜそうするのか、具体的にどうやるのかを、わかりやすいサンプルコードで説明されていた。
特に「実装パターン」の中の「Value Object」は、大きな転機になった。 この転機については、 masuda220.jugem.jp で書いた通り。
「実装パターン」を何度も読み直して、いろいろ実践してから、「ドメイン駆動設計」、「リファクタリング」、「オブジェクト指向入門」、「オブジェクトデザイン」を読み直してみたら、それぞれの本の内容がだいぶわかるようになってきた。 特に「ドメイン駆動設計」の現場でのエヴァンスの設計に奮闘するさまざまなエピソードが、生きた事例として理解できるようになってきた。
その後、ドメインを隔離する、アグリゲートやリポジトリー、境界づけられたコンテキストとモデルの整合性パターンなどが主たる関心事になって、現場での設計に取り入れるようになった。効果もそれなりに感じていた。
もやもや感
ドメイン駆動設計については、現場で実践するだけではなく、ブログを書いたり、イベントで登壇したり、他の現場に出かけて意見交換や助言をしたり、本を書いたり、いろいろアウトプットをしてきた。
アウトプットしながら、新たな気づきがあり、また次の実践とアウトプットということを繰り返してきた。
しかし、どうもすっきりしないもやもや感を抱えていた。 簡単に言えば、表面的形式的には実践できているかもしれないが、本質をとらえ切れていない、あるいは、本質を言語化できていない、という違和感。 エヴァンス本にでてくるブレークスルー的な手ごたえはなんどか経験できたが、偶然感がつよく、もっと意図的にそこに近づく道があるのでは、という漠然とした予感めいたもの。
三つのキーワード
去年の夏に、あるイベントのワークショップ用に資料を作っている時に、その違和感を解消する手がかりをつかんだ。 ドメイン駆動設計と他の設計方法を比較して説明するスライドを作っていた時だった。
その時点では、まだうまく言葉で表現できていなかったが、それから数か月、自分なりにその感触を整理して言語化しようとしてみた。 イベントやワークショップで、実際にいくつかのキーワードを使って説明し、その反応を受けとる中で、三つのキーワードが明確な概念として登場してきた。
それが次の三つのキーワード
- ビジネスルール
- 計算モデル
- 型指向のプログラミング
ビジネスルール
エヴァンス本に繰り返しでてくる「ドメインロジック」「ドメインの知識」「ドメインの理解」などの言葉は、具体性に欠ける。 対象が広くぼんやりとしている。
「ドメインロジック」をビジネスアプリケーションの分野に限定すれば、ビジネスロジックとなる。 そして、ビジネスロジックはビジネスルールとほぼ同じ意味になる。
ビジネスロジックとビジネスルールを区別するとすれば、ビジネスルールは、プログラムで表現するかしないかとは無関係な、実際のビジネスの活動の中の取り決めや約束事。ビジネスロジックは、ビジネスルールのある部分をプログラムで表現したもの。
いずれにしても「ドメインロジックに焦点を合わせる」は「ビジネスルールに焦点を合わせる」と捉えることができる。 実際のところ、エヴァンス本にも「ルール」という言葉は300回近く登場する。「ポリシー」や「制約」という言葉も含めれば、ドメイン駆動設計の重要な関心事の一つが「ビジネスルール」にあることはまちがいない。
「ドメインロジック」を「ビジネスルール」と置き換えてみると、エヴァンスの意図するところが、より具体的に理解できるようになる。
ドメインの知識とは「ビジネスルールの知識」であり、ドメインエキスパートとは「ビジネスルールについての知識と経験が豊かな人」というわけだ。
ドメイン駆動設計の考え方を理解し実践するためには「ドメインロジック」を「ビジネスルール」という、より具体的な対象としてとらえることがカギになる。
計算モデル
「ドメインモデル」も、あいまいでわかりにくい言葉だ。
エヴァンス自身が書いているように、ドメイン駆動設計でいうところの「ドメインモデル」はオブジェクト指向のコミュニティで生まれた設計の考え方の一部をなしてている。 オブジェクト指向も、いろいろな解釈があるが、私自身は、データモデルへの対比という意味も含めて、オブジェクト指向のモデルとは「計算モデル」だと思っている。
実際に、エヴァンス本に登場するドメインモデルの例は、次のような計算モデルである。
- 投資シンジゲートの配分比率計算(シェアパイ)
- コンテナへの荷物の格納ルール
- 輸送経路を自社に有利にするための経路選択バイアスポリシー
- プリント基板の配置ルールを基にした部品配置と配線の妥当性の判定
ドメインモデルというのは、なんらかのルールに基づいた「計算と判定のモデル」ととらえると、だいぶすっきりする。
アプリケーション全体としては、データを永続化したり参照したりするための仕組みが必要になるが、「ドメインモデル」に焦点をあわせれば、データの記録と参照とは分離された、純粋な「計算モデル」という理解がしっくりくる。
リポジトリや集約の説明のところで、データの永続化の問題が登場するために、この「ドメインモデル=計算モデル」という図式が、ぼやけてしまっている。しかし、全体を読めば、ドメインモデルは「計算と判定のモデル」であり、「データの記録と参照」からは隔離されたものとして扱われていることがわかる。
型指向のプログラミング
計算モデルをプログラミング言語で表現する場合、Fortranのように手続き型の言語でももちろんできるが、エヴァンス本が採用している実装技法は、オブジェクト指向である。 エヴァンス本人が、あるイベントで述べているように、本を書いた当時は "I loved Object Oriented." 、 現在は "I still like it" と続けている。温度感は変わっているが、オブジェクト指向が基本であることは変わっていない。
問題は「オブジェクト指向」といってもいろいろなとらえ方があること。 ここらへんの詳しい話は、以下の説明が必読。
簡単に言えば「メッセージパッシング」で代表されるオブジェクト指向と、「型」で代表される、本質的に異なるオブジェクト指向があるということ。 エヴァンス本を読むと、若干の混乱があるが、基本的には「型」を基本とするオブジェクト指向と理解してまちがいないだろう。
ビジネスルールを「計算モデル」ととらえ、計算モデルをコードで表現するには、「型」に基づくオブジェクト指向プログラミングが役に立つ。
「型」とは、計算の対象となる「値の種類」であり、有効な値の範囲と、その値を使った計算を定義したもの。 計算モデルの表現技法として、型指向のプログラミングがぴったりというわけだ。
エヴァンス本の、配分比率の計算、コンテナの格納条件の判定、経路選定のバイアス計算などは、型指向でプログラミングする具体例になっている。暗黙の概念を明示したり、制約を表現したり、設計の意図を明確にし、変更を楽に安全にする技法として、クラスを使って型を定義するプログラミングスタイルを採用している。
実際、価格計算とか日付計算がともなうビジネスルールでは、型指向のプログラミングで記述することで、ロジックを一か所にまとめてわかりやすく整理できる。 値を「型」として扱う設計パターンの代表であるValue Object パターンは、ビジネスルールの計算モデルを実装するための、基本であり最強の道具だということ。
実験は続く
「ビジネスルール」「計算モデル」「型指向のプログラミング」の三つのキーワードでドメイン駆動設計を解釈し、実践してみる実験は、まだはじめたばかり。 自分としては、そうとう手ごたえを感じているけど、実際のコードでもっともっと実験し小さな失敗を繰り返しながら、知見を増やし、こうやってブログで書いたりイベントで登壇したり、いろいろな現場で設計に関心とエネルギーを持つ技術者たちと意見交換をすることで、さらに多くの学びができそうな予感にわくわくしている。
参考情報
ビジネスルール・計算モデル・型指向のプログラミングで作ってみたサンプルアプリケーション github.com
このサンプルアプリケーションを解説したときに使った資料 https://www.slideshare.net/masuda220/edit_my_uploads
設計ガイドライン · masuda220/business-logic-patterns Wiki · GitHub
参考書籍: gihyo.jp