ドメイン駆動設計を実践するために

ドメイン駆動設計の実践に向けて、DDD本では明示的に語られていない視点からドメイン駆動設計をとらえ直す。

導入

ドメイン駆動設計入門では、かなり抽象的なレベルでDDD本の根底にある思想を概観しました。一言で要約すれば「ドメインエキスパートの頭の中にあるドメインをとらえるモデルを共有し、オブジェクト指向パラダイムを用いて、それをソフトウェアの実装に落とし込む」という構想であると言えるでしょう。これを踏まえて今回は、実践のためには何が必要なのか、という問題意識からドメイン駆動設計をとらえ直してみたいと思います。


今回のポイントはプロセスです。DDD本ではほのめかされているにすぎない「モデリングのために行われているもの」に焦点を合わせて、設計とプロセスをどのように融合させていけばよいのかを考えていきたいと思います。ここでの目的はDDD本を批判することではなく、語られない点からとらえ直すことで、ドメイン駆動設計全体に対する理解を深めることにあります。

DDDにおけるプロセス

プロセスとデザインの関係は序文でも語られていますが、そこでのプロセスを見る視点は「イテレーティブ」という開発の性質や、「ドメインエキスパートと開発者との間のインタラクション」という要素にフォーカスされています。ただし、これらについては「アジャイル」と一言で片付けるべきではありません。


イテレーティブなプロセスに関しては、第三部においてモデルの進化はリニアなものではなく、ドメインに対する洞察が深まった時に、突然ブレイクスルーが起きるのだと説明されています。「深いモデル」という概念を使って、モデルレベルのリファクタリングの重要性が説かれているのは大きな特徴と言えるでしょう。また、インタラクションに関しても、モデルを構成する概念を整えていく上で、「会話すること」の重要性が挙げられます。これは会話の中で使うことで、言語としての不十分な部分が際立つことになり、自然と改善されていくという構想です。


こうしたことが、DDD本で語られているプロセスについての考え方と言えます。それでは、いくつか補助線を引くことで語られていないことからDDDの思想を浮かび上がらせていきましょう。

内側と外側

Trygve ReenskaugとJames Coplienは、Doug Engelbartの「コンピュータとは人間の精神を拡張したものである」という思想に端を発する潮流が現在に残したものについて、「インタラクティブでグラフィカルなユーザインタフェースと、世の中のプログラミングにおけるオブジェクト指向言語の隆盛である」とします*1。これはつまり、「ユーザのメンタルモデルを表現するためのパラダイムとしてのオブジェクト指向」と「ソフトウェアの内部に持ち込まれたモデルを操作するためのインタフェース」ということになるのですが、この2つは、実はソフトウェアにおける「外側」と「内側」という2つの側面を端的に表したものであるとも言えます。


このような区別をした場合、ドメイン駆動設計は徹底して「内側」を指向していると言えます。通常であればユーザがシステムについて考える際のインタフェースになるのは、画面や帳票といった文字通りのユーザインタフェースです。したがって、ユーザとのやり取りも、画面や帳票を見せて「この画面ってこういう作りでいいですか?」と確認するものになりがちですが、ドメイン駆動設計においては、ドメインモデルの構造をダイレクトにユーザに見せた上で「ここってこういう考え方でいいんでしょうか?」というやり取りをしようとします。だからこそ、手続き型の実装が嫌われ、表現力のあるモデル/設計が求められることになるのです。


逆に画面/帳票イメージはほぼ登場しません。強いて言えば、第6章の中で集約(AGGREGATE)とロックの関係について議論する際に、画面か帳票のようなもののイメージを使っているくらいで、ユーザと仕様を確認するためのインタフェースという意味での画面/帳票は一切ありません。ただ、実際のソフトウェアを作る上ではユーザインタフェースなしで済ますことはできませんので、ユーザインタフェースをどう設計するか、あるいはユーザインタフェース層とアプリケーション層に対して、ドメイン層をどう組み込んでいくか、ということは、別途考えなければならないことになります。


こうした観点から見直すと、DDD本の中に「クライアント開発者」というロールが見え隠れしていることに気づきます。ドメインモデルが活動する空間となるドメイン層の手前に、アプリケーション層が存在するのと同じように、ドメインモデルを使用してアプリケーションの機能を実現する役割を担った開発者がどうやら存在しているようなのです。一例を示しましょう。

INTENTION-REVEALING INTERFACE
Name classes and operations to describe their effect and purpose, without reference to the means by which they do what they promise. This relieves the client developer of the need to understand the internals.


意図の明白なインタフェース
クラスと操作の名前をつける際には、効果と目的を記述すること。やると約束したことを行う手段には言及してはならない。こうすることで、クライアント開発者はインタフェースの内部を理解しなくてよくなる。
DDD p.247


こうしたクライアント開発者は実装されたモデルを使用しつつ、アプリケーションとしてのふるまいを実装する責任を担っているのであろうと推測されます。

構造とふるまい

同じことを、少し視点を変えて考えてみましょう。ReenskaugとCoplienの両氏はオブジェクト指向について、構造を表現することには長けていたが、ふるまいについてはうまくとらえることができていないと批判し、そこからDCIアーキテクチャの構想を展開していきます。この構造とふるまいという二項対立はドメイン駆動設計においてどう考えるべきでしょうか。


ドメイン駆動設計のモデルが表現しようとしているものが構造だけかと問われれば、それはやはり違うと答えるべきでしょう。しかし、「ふるまいも表現しようとしている」と言い切ってしまうとおそらく語弊があります。ドメインモデルにおいて表現されるふるまいは、そのモデルもしくはそのモデルを構成する概念にとって本質的なふるまいです。逆に言えば、ユーザインタフェースからの入力に対するユーザインタフェースを使った出力という、いわゆる「アプリケーションとしてのふるまい」には言及されていないのです。しかし、実は普段私たちがソフトウェア開発に際して考えているのは、こうした「外側から見たふるまい」なのではないでしょうか。


ドメインモデル設計が「内側」における「ドメインモデルとしてのふるまい」にこだわっている一方で、なんらか「外側」から見た「アプリケーションとしてのふるまい」も考えなければいけないのだとすれば、この両者を統合する視点が必要になるでしょう。

「実験」

DDD本の中に頻出する概念の一つに「実験」(experiment)があります。これが外側と内側を統合する上での鍵を握っています。この実験という概念が分かりやすく使われている箇所をDDD本の中から引用します。

The language, combined with sketches and a brainstorming attitude, turned our discussions into laboratories of the model, in which hundreds of experimental variations could be excersized, tried, and judged. As the team went through senarios, the spoken expressions themselves provided a quick viability test of a proposed model,...


言語をスケッチやブレインストーミングと組み合わせることで、我々の議論の場はモデルの実験室に変わった。そこではモデルの実験用バリエーションを数多く使用し、試し、使えるかどうかを判断することができた。チームがシナリオを詳細に検討する際には、口にする表現自体が、提案されたモデルが実現できるかを調べる簡易的なテストになった。
DDD p.13

つまり、モデルを作成し、共有することはできますが、そのモデルが正しいかどうかを検証することは、モデルだけではできません。モデルの検証は「外側」から、具体的にはシナリオを使って実現されます。実際のシナリオに対して、モデルがどうふるまうかを考えることにより、モデルを検証することができるのです。


こうしたウォークスルーで使用されるシナリオの具体例は、第7章をはじめとして、何ヶ所かで登場します。しかし、そういったシナリオをどういう観点から作成するべきか、あるいはどういうプロセスで作成できるのかということは語られません。したがって、この部分はDDDを実践する際に、自分で橋渡しをするべき場所であると言えます。


こうした観点から見た時に1つのヒントになるのが「ふるまい駆動開発(BDD:Behaviour Driven Development)*2」です。BDDとは、要約すれば、これはテスト駆動の視点を「テスト」から、顧客にとっての価値をもたらす「ふるまい」にシフトさせた考え方であると言えるでしょう。ここで重要なのは、「顧客にとっての価値」という視点です。顧客にとって価値をもたらす、外側から見たときのふるまいが記述できるのであれば、Given/When/Then形式のユーザストーリーであっても、より詳細なユースケース記述であっても、適切なものを選択すればよいと思います。ただ、その仕様が実行可能な形式で記述できていればより好ましいということです。こうしたソフトウェアに対する外側からの記述と、ユーザのメンタルモデルを忠実に表現した内側の実装が疎通した状態を、常に保ち続けること、それはソフトウェア開発における理想型と呼べるものでしょう。

まとめ

内側と外側、およびその疎通という観点から、DDDについて整理してみました。メンタルモデルの実装に関してDDD本では実に深いレベルで記述されていますし、ここでいう外側についても豊かな示唆に富んでいます。顧客の価値を実現可能な形に記述しつつ、効率的にソフトウェアとして実装していくという価値の流れの中に、ドメイン駆動設計を適切に位置づけることは、私たちに与えられた宿題なのかもしれません。




Domain-Driven Design: Tackling Complexity in the Heart of Software

Domain-Driven Design: Tackling Complexity in the Heart of Software

The RSpec Book: Behaviour Driven Development with RSpec, Cucumber, and Friends (The Facets of Ruby Series)

The RSpec Book: Behaviour Driven Development with RSpec, Cucumber, and Friends (The Facets of Ruby Series)