[注] このページは「オブジェクトの広場」「同名の記事」を、プリンタで印刷しやすいように整形したものです。必要に応じて原典を参照してください。

DDD難民に捧げる
Domain-Driven Designのエッセンス
第1回 ドメイン駆動設計とは

「ドメインモデリング」は、アプリケーション開発において最も重要な部分だとされています。しかしその割には、フレームワークの使い方やアーキテクチャの設計方法など技術に関する解説書はたくさんあるものの、ドメインモデリングそのものを扱った書籍はほとんど無かったと言ってもいいでしょう。Eric Evansの『Domain-Driven Design』(以降DDD)は、「ソフトウェアの真の複雑さに挑戦する」という副題からも分かるように、ドメインモデリングに正面から取り組んだ待望の書籍です。

DDDは、海外では非常に評判の高い書籍です。本書の出版前からMartin Fowler氏により「期待できる内容だ」と推薦されていたり、GoFの1人であるRalph Johnson氏は自身のブログで本書を「4、5回は読み直した」と賛辞を送っています。Spring Frameworkの開発者Rod Johnson氏も、最近のプレゼンテーションでDDDを紹介しながら、「Java EE開発者がこれから進むべき道はリッチなドメインモデルだ」と発表しています。また、MDAツールSculptorのように、DDDを積極的に採用したツールやフレームワークも登場しつつあります。

しかし、日本では翻訳書がいまだに出版されていないこともあり、本書の出版から3年近く経った今でも、まだまだ一部の通の人たちにしか広まっていないように筆者には思われます。また、原書を読まれた方の中からも「本が分厚すぎて読みきれない・・・」という嘆きの声も聞かれます(DDD難民という言葉もあるそうです)。そこで本連載では、全3回に分けて、DDDの全貌を簡潔に紹介してみたいと思います。

DDDはタイトルからは一見分かりにくいのですが、いわゆるパターン本の1つです。しかし、DDDは全体が読み物の体裁で編まれているため、パターンカタログが読み物から独立しているもの(『デザインパターン』『J2EEパターン』『エンタープライズアプリケーションアーキテクチャパターン』など)に比べ、パターンの閲覧性は良くありません。本連載では、すでに一度読破された方にも有用な資料となるように、パターンカタログとしてDDDを再構成してみます。

ドメイン駆動設計(Domain-Driven Design)とは

まずは、DDDとは何か、から始めましょう。そもそも「ドメイン」とは、アプリケーションが対象とする業務領域のことです。本書では、ドメインを「知識、影響力、活動の一領域」と定義しています。業務アプリケーションでは、アプリケーションをプレゼンテーション層、ドメイン層、データソース層の3層に分けるアーキテクチャが主流ですが、このドメイン層がユーザの業務に直接的に関わる部分になるわけです。したがって、ドメイン層を正しく構築できるかどうかが、そのままアプリケーションの成否に影響します。

DDDは、オブジェクト指向コミュニティの間で長年培われてきたドメインモデリングのノウハウやベストプラクティスを集大成した、1つの設計思想/哲学です。ドメインモデルをこれから構築しようとする人に、設計上の判断を下すための枠組みと、ドメイン設計について議論するためのボキャブラリを提供するものです。TDD(Test-Driven Development、テスト駆動開発)やFDD(Feature-Driven Development、ユーザ機能駆動開発)と一見名前は似ていますが、DDDはなにか新しい開発プロセスを提唱するものではないことに注意してください。ただし、DDDは基本的にアジャイルな開発プロセスを前提にしています。

ドメインモデルを中心にすえた設計思想

DDDとはどんな設計思想かを簡潔に説明すると、ドメインモデルをソフトウェア開発の中心にすえ、コードやコミュニケーションを常にドメインモデルと一体化させながら、ドメインモデルを反復的に深化させることでより価値の高いアプリケーションを生み出していこうとする考え方です。ドメインモデルをすべての中心に置くので、「ドメイン駆動」というわけです。

DDDの要点は、次の3点にまとめられます。

  • ドメインモデルは、ドメイン知識を深めながら反復的(iterative)に深化させていく
  • ドメインモデルが、開発者とドメイン知識をもつ人(ユーザ、専門家等)との間の共通言語となるようにする
  • ドメインモデルと実装コードとがきちんと対応付けられるようにする

DDDでは、1回きりの開発で完璧なドメインモデルを設計できるとは考えません。優れたモデルは、何度かアプリケーションのリリースを繰り返す中でようやく得られるものと考えます。こうしたドメインモデル探究の過程では、当然ドメイン知識をもった専門家との対話が不可欠です。開発者と専門家の間で誤解のないコミュニケーションを行なうには、ドメインモデルを専門家が理解できる言葉で構築する必要があります。さらに、ドメインモデルの深化がアプリケーションに正しく反映されるには、実装コードがドメインモデルと対応付けられていなければなりません。逆に、モデルを実装していく過程で、新たなドメイン知識を発見することもあるでしょう。ドメインモデルと実装コードには、双方向の関連付けが必要となります。

DDDはパターン本の1つ

DDDは、上記のノウハウをパターンの形式で体系化しています。書籍タイトルに「〜 Patterns」「Patterns of 〜」などと入っていないため気付きにくいのですが、DDDはれっきとしたパターン本の1つです。

DDDパターンは、Alexander形式を採用しています。Alexander形式とは、パターン言語の生みの親である建築家のChristopher Alexander氏が、建築のパターンを記述するのに用いた形式です。最初に写真やイラストなどの「イメージ」が掲載され、「文脈」「問題の記述」、間に「Therefore(ゆえに)」という言葉を挟んで「解決法の記述」「結果/実装上の考慮/例」、最後に「次の文脈」という構造になっています。しかし、有名なGoFのデザインパターンとは違い各項目がはっきりと節に分かれておらず、パターンのことを意識せずにそのまま読み物として読めるのが特徴です。

DDDに収録されているパターンは、全部で40あります。アンチパターンも含めると、41パターンになります。

本書は4部構成になっており、したがってDDDパターンも4つの分類に分かれます。

  1. Putting the Domain Model to Work (ドメインモデルを動かす)
  2. Building Blocks of a Model-Driven Design (モデル駆動設計の基本要素)
  3. Refactoring Toward Deeper Insight (さらなる洞察へ向けたリファクタリング)
  4. Strategic Design (戦略的デザイン)

第I部のパターンは、DDDの目標を示したものです。第II部では、ドメインモデリングの基礎的なベストプラクティスをパターンにまとめています。第III部は、ドメインモデルをさらに深めていくためのより実践的なパターンを説明します。最後の第IV部では、1アプリケーションの範囲を超えて、他のシステムとの連携が必要なアプリケーションや、複数のドメインが関係する大きなプロジェクトでDDDを実践するためのパターンが示されます。

SOAにも通ずる設計思想

DDDが単一アプリケーション内のドメインモデルの作り方についてだけ語っているものだと考えてしまうのは、DDDの一面だけしか理解しないことになります。本書の大きな部分を占める第IV部「Strategic Design」は、1アプリケーションのレベルを超えて、経営戦略的(strategic)な視点を必要とするシステム開発の舞台でDDDを実践する方法を提示しているからです。

SOAはいま、バズワードと言えるほどに注目を集めています。JBI(Java Business Integration)、SCA(Service Component Architecture)といったSOAの技術標準はすでに出揃っていて、標準に準拠したESB/BPM製品も充実しています。しかし、SOAを本当に成功させるには、単にそうした技術に習熟するだけではダメで、SOAを正しく構築する開発方法論が必要になるはずです。残念ながら、市場における技術標準やツールの充実とは対照的に、私たちが利用できるSOA開発方法論はまだまだ成熟していないのが現状です。

DDDが教える「戦略的デザイン」はSOAに特化したものではありませんが、私たちがいま必要としているSOAの方法論に大いに示唆を与えてくれる内容になっています。

アナリシスパターンとの違い

最後に、ドメインを扱うもう1つのパターンである『アナリシスパターン』(Martin Fowler著)との関係についても触れておきましょう。

アナリシスパターンとは、分析(analysis)のパターンです。デザインパターンがオブジェクト指向設計の中で繰り返し現れる構造をパターン化したものであるように、アナリシスパターンはドメイン分析の中で繰り返し現れる構造をパターン化したものです。「量」「勘定」「計画」「ポートフォリオ」「先物取引」など、再利用可能なドメインモデルがパターンとしてまとめられています。

アナリシスパターンとDDDの違いは、アナリシスパターンが「ドメインモデル」のパターンであるのに対し、DDDは「ドメインモデリング」のパターンであるということです。アナリシスパターンはドメインモデルの具体例を提供するものであり、DDDはどうやってドメインモデルを構築すればよいかを教えてくれるものです。

DDDにとっては、アナリシスパターンのモデルはドメインモデル探究の最初の出発点として利用したり、すでに構築されたドメインモデルを改良するためのヒントとして利用したりできるものです。DDDの第11章「Applying Analysis Patterns」では、実際に「在庫管理と会計」に関するいくつかのアナリシスパターンを使って、ドメインモデルを洗練させていく過程が説明されています。

DDDパターンカタログ

前置きが長くなってしまいましたが、ここから肝心のパターンカタログに移ります。DDDに収録されたパターンを1つ1つ紹介していきましょう。今回は、第I部「Putting the Domain Model to Work」にあるパターンを取り上げます。

I. Putting the Domain Model to Work(ドメインモデルを動かす)

第I部では、DDDが目指すべき最終的な目標を明確にします。ドメインモデルが有機的に機能し、開発プロジェクトを駆動するエンジンになるとはどういうことなのかを、パターンによって示します。登場する3つのパターン「ユビキタス言語」「モデル駆動設計」「実践的モデラー」は、DDDの基本3ヶ条とでもいうべきものです。

● Ubiquitous Language(ユビキタス言語)パターン

ドメインを正しく捉えた柔軟で価値の高いソフトウェアを設計するには、チームの共通言語を創造しなければならない。共通言語はユーザ、ドメインの専門家から、設計者、プログラマまで、分析/設計モデルからプログラムコードに至るまで、プロジェクトのすべての関係者、成果物に行き渡っていて、同じ意味で理解されるようなユビキタス(遍在的)な言語である。ドメインモデルがユビキタス言語となるようにし、ドメインモデルを介してプロジェクトが一体となるようにする。

● Model-Driven Design(モデル駆動設計)パターン

ユビキタス言語を実現するには、プログラムコードにおいてもドメインモデルが正確に表現されていなければならない。ドメインモデルとプログラムコードとが常にお互いを反映するように保つことで、ドメインモデルの変更がそのままコードの修正を促し、逆にコーディングの中で得られた新たなドメイン知識が即座にドメインモデルに反映されるようになる。このようにモデルとコードを緊密に結びつけるのがモデル駆動設計(MDD)である。MDDを実践するには、開発ツールやオブジェクト指向プログラミング(OOP)のようなプログラミングパラダイムが必要になる。

● Hands-On Modeler(実践的モデラー)パターン

もしモデラーがプログラムを書けなかったり、プログラマがドメインモデルに興味を示さなかったら、MDDの利点であるモデリングとプログラミングの好循環は生まれない。また、チームのコミュニケーションもそこで停滞してしまう。MDDを通してユビキタス言語を実現するには、モデラーが動くプログラムを書けなければいけないし、同時にプログラマがドメインモデルを理解し、修正できなければならない。つまり、チームのすべての開発者は、プログラムを書くモデラーでなければならない。

[補足] DDDとMDD、DDDとオブジェクト指向

DDDとMDDは一見よく似た概念で、DDDの中でそれぞれがどのように位置付けられているのか分かりにくいところがあります。両者の違いについては、著者Eric Evansが「Domain-Driven / Model-Driven」という記事で説明しています。

内容を簡単に解説すると、DDDとは「ドメイン」を最も重視し、それをすべての中心に置く方法です。MDDは「モデル」を元に行なう設計技法を指します。ドメインの複雑さを理解し、ソフトウェアに反映させる最も良い方法はモデルを使うことである(とDDDは仮定する)ために、DDDはその実現方法の中心にMDDを採用します。一方で、MDDは必ずしもドメインだけが適用範囲ではありません。UIやアプリケーションフレームワークなど、純粋に技術的なものにも適用できます。MDDはDDDにとって必須ではないが、ごく自然な伴侶という関係になります。

もう1つ、DDDとオブジェクト指向(OO)との関係についても触れておきます。「ドメインモデリング = OO」と思いがちですが、DDD自体は必ずしもOOを前提としたものではありません。ただ現実的には、MDDを実現できる最良のプログラミングパラダイムがOOPであるために、OOが積極的に使われているということです。関数型プログラミングでMDDが実現できるのであれば、それでも構わないわけです(関数型が有効なドメインは限られているとは思いますが・・・)。

同様に、DDDではモデリングの記法にUMLを使うことも必須ではありません。DDDでは、UMLに囚われることなく、ドメインをより良く理解できる記法があれば、それを積極的に採用することを推奨しています。

II. Building Blocks of a Model-Driven Design(モデル駆動設計の基本要素)

第II部では、DDDの要であるMDDを実現するための基礎が説明されています。ここでは、いわゆるオブジェクト指向設計のベストプラクティスが、ドメインモデリングの観点からまとめ直されることになります。

DDDは、既にあるオブジェクト指向設計の原則やプラクティスと矛盾するものではありません。著者自身が書籍で述べているように、DDDはRebecca Wirfs-Brockの「責務駆動設計(Responsibility-Driven Design)*1や、Bertland Meyerの「契約による設計(Design by Contract)」を背景にもっています。また、Craig LarmanのGRASPパターンなど、広く知られた他のオブジェクト指向設計のプラクティスとも一致します。

DDDをMartin Fowlerの『エンタープライズアプリケーションアーキテクチャパターン』(PofEAA)経由で知った方も多いかもしれませんが、第II部はこのPofEAAとも非常に関連が深い部分です。PofEAAでお馴染みのパターンが、ここでもいくつか登場します。

*1 ちなみに、このRebecca Wirfs-Brockの書籍『Object Design: Roles, Responsibilities, and Collaborations』の邦訳(邦題『オブジェクトデザイン』)が今年の9月上旬に出版予定です。私も一査読者として翻訳に協力させていただきました。このオブジェクトの広場にて、近々改めて書籍紹介をしますのでぜひお楽しみに。

ドメイン層の分離

ドメインモデルとプログラムコードとの緊密な連携のためには、まず何よりもドメイン層を他の関心事(プレゼンテーション、データアクセスなど)から分離する必要があります。

● Layered Architecture(層状アーキテクチャ)パターン

ビジネスロジックがユーザインタフェース(UI)、永続化などのロジックと一緒になっていると、UIの些細な変更がモデルに影響したり、モデルを修正するために低レベルなデータアクセスのコードをいじらなければならなくなったりする。ドメインモデルとコードとを結びつけるMDDを実践するには、ビジネスロジックがUIやデータアクセスのコードから切り離されていなければならない。ソフトウェアを以下の4層に分けることで、純粋かつ明確なドメインモデルをドメイン層の中に構築することができる。

  • UI層 … ユーザとの相互作用の境界となる層
  • アプリケーション層 … ドメインオブジェクトを操作することで、ソフトウェアが果たすべき仕事を実現する層
  • ドメイン層 … ビジネス上の概念を表現する層
  • インフラストラクチャ層 … 上の3層を支える技術的な基盤となる層

● Smart UI(利口なUI)アンチパターン

層状アーキテクチャの対極をなすアンチパターン。ビジネスロジックやデータアクセスのコードが、UIのコードと一緒になってしまっている、いわばスパゲッティな状態。利口なUIと呼ぶのは、ビジネスロジックを含むすべての処理がUIの中で行なわれるから。最もやっつけで手軽なやり方がこれなので、設計を何も考ないとこの状態に陥ってしまう。開発チームのスキルが低くて、かついわゆる第4世代(4GL)と呼ばれるようなグラフィカルな開発ツールを最大限に利用する場合は、このパターンの採用にも一理ある。しかし、利口なUIを採用してしまうとMDDが一切機能しなくなるので、DDDは諦めるしかない。

ソフトウェアによるモデルの表現

ドメインモデルの構成要素は、大きく「エンティティ」「値オブジェクト」「サービス」の3つに分類できます。また、それらをまとめる「モジュール」も、ドメインモデルの重要な構成要素になります。

● Entities(エンティティ)パターン

オブジェクトの中には、アイデンティティをもつもの(エンティティ)が存在する。エンティティは、アイデンティティが同じならば、属性が異なっていても同一のものとして扱わなければならない。逆に、属性がまったく同じでも、アイデンティティが違えば当然別エンティティとなる。エンティティはドメインモデルの主役であり、そのライフサイクルを考えることが重要になる。ドメインモデルの中において、エンティティの同一性をどうやって判断するかを定義しなければならない。

● Value Objects(値オブジェクト)パターン

エンティティとは逆に、たとえば「色」や「量」のように、その属性だけが重要で、アイデンティティを考えることに意味のないオブジェクトもある。そうしたオブジェクトは、値オブジェクトに分類する。値オブジェクトとは、事物の性質を表現するものである。値オブジェクトは状態を変更できないもの(immutable)として扱う。エンティティの複雑さに専念できるように、値オブジェクトはシンプルな設計に保つようにする。

(この値オブジェクトは、PofEAAのValue Objectパターンと同じものを表している)

● Services(サービス)パターン

ドメインで扱う概念の中には、1つの機能や処理が単体で存在していて、もの(オブジェクト)として扱うのが不自然なものもある。そうしたものは、サービスという形でユビキタス言語に組み込む。サービスは基本的に状態をもたない(stateless)。

(PofEAAのService Layerパターンとは異なる概念なので注意。Service LayerパターンはDDDのアプリケーション層に相当するものを言っているが、DDDのサービスはドメインモデルの中にあるサービス的なものを指している。邦訳はないが、Fowler氏の記事「Evansの分類」も参考になる)

● Modules(モジュール)パターン

モジュールの仕組み(Javaのパッケージや.NETの名前空間など)は、プログラミングにおいては誰もが使っている。人間が一度に考えられる物事の量には限界があるので、概念についても同じようにモジュール分割が必要である。プログラミングの場合と同じく、ドメインモデルのモジュール分割においても高凝集/低結合が重要な目安になる。関連し合う概念同士はひとつにまとめ(高凝集)、かつ一度に考えなければいけない範囲は最小限にする(低結合)。モジュールの名前も、ユビキタス言語の重要な一要素として扱う。モジュールもコードと同様、リファクタリングによってアジャイルに進化させていかなければならない。

ドメインオブジェクトのライフサイクル

オブジェクトには、生成から消滅までのライフサイクルがあります。またその生存期間中に、一時的にデータベース(DB)上に保存されたりもします。こうしたオブジェクトのライフサイクルも、ドメインの設計に組み入れなければなりません。

● Aggregates(集約)パターン

オブジェクトのライフサイクルを設計するには、まずライフサイクルの単位となるオブジェクトのまとまりを考えなければならない。たとえば「注文」と「注文明細」のように、関連するオブジェクトのグループは集約として扱い、集約を単位としてモデルの他の要素との境界を明確に分ける。集約の中から1つエンティティを選んで、それを集約のルート(root)とする(先ほどの例では、「注文」がルートになる)。1回きりの処理で参照が破棄されるような特別な場合を除いて、外部から参照できるのはルートだけで、中のオブジェクトに対する処理はすべてルートが中継する。こうすることで、集約内のモデルの一貫性を維持することができる。

● Factories(ファクトリ)パターン

オブジェクトや集約の生成処理はそれ自体複雑になりうるため、ファクトリを導入して生成処理をカプセル化*2する。オブジェクトの生成そのものがドメインモデル上で重要な意味をもつことは(ほとんど)ないため、ファクトリはドメインモデルの一部ではない。あくまで、ドメインの設計上必要な一要素、という位置付けになる。

*2 本来「カプセル化」とは単に属性や操作を1つにまとめることを表す概念で、実装の詳細を外部から隠す概念である「情報隠蔽」とは異なります。しかしEvansはこの2つを混同して使っていて、カプセル化という言葉を情報隠蔽の意味でも使っていることに注意してください。

● Repositories(リポジトリ)パターン

ファクトリにより生成されたドメインオブジェクトは、役目を終えて破棄されるまでは生存する。生存期間の途中で、ほとんどの場合はDBなどにいったん永続化される。DBへの永続化や問い合わせ処理の複雑さによって、ドメインモデルが汚染されないようにするため、リポジトリという永続化/問い合わせ専用オブジェクトをドメイン設計に導入する(ファクトリ同様、ドメインモデルの一部ではない)。リポジトリを使う側からは、ドメインモデルがあたかもメモリ上にコレクションとして存在しているかのように見える。リポジトリは、モデル中でグローバルなアクセスが必要なエンティティ集約の場合はそのルート)毎に、1つ用意される。

(このリポジトリは、PofEAAのRepositoryパターンと同じものを表している)

III. Refactoring Toward Deeper Insight(さらなる洞察へ向けたリファクタリング)

ここまでで、ドメインモデル構築の基本的な道具が揃いました。しかし、ドメインの専門家やユーザの頭の中にある知識をより良く反映した「深いモデル」(deep model)を得るには、継続的な改善が必要です。DDDのモデリングは、「名詞がクラスになって動詞がメソッドになる」というような、古典的な単純化されすぎたOO方法論とは異なります。優れたドメインモデルの設計に到達するには、イテレーションを繰り返さなければならないのです。

著者Eric Evansは、リファクタリングを次の3つのレベルに分類しています。

最初の2つは、技術的な観点から設計の質を高める従来のリファクタリングです。つまり、コードが「何をするのか(What)」を分かり易くするものです。一方DDDが提唱するドメインリファクタリングとは、ドメインに対する深い洞察をモデルに反映させるためのリファクタリングです。コードが「何故そうなっているのか(Why)」まで明らかとなるように、コードとモデルとを改善していくのです。

絶え間ないドメインリファクタリングを可能にするのが、コードの変更を容易にする「しなやかな設計」(supple design)です。MDD実践の真髄は、この「深いモデル」と「しなやかな設計」の2本柱によって成り立つのです。

*3 『パターン指向リファクタリング』の著者Joshua Kerievsky氏は、DDDをAlexander形式のパターン本にするよう促した張本人でもあるそうです(DDDの謝辞を読んでみてください)。

深いモデル ― 隠れた概念の発掘

「深いモデル」を得るには、ドメインに隠された概念を見つけ出す必要があります。見つけづらい概念には、経験上「制約」「プロセス」「仕様」に関するものがあります。*4

*4 仕様パターンは、元々Eric EvansがMartin Fowler氏との共著で、1997年のPLoP(Pattern Languages of Programs)カンファレンス(ソフトウェアパターンの国際会議)において発表したものです。ここで1つだけパターンを取り上げているところに、著者のこのパターンへの思い入れを感じます。

● Specification(仕様)パターン

isXxx()のような真偽値を返すメソッドからなるビジネスルールは、通常のエンティティ値オブジェクトには上手く割り当てられない。ビジネスルールをドメインモデル上で表現するには、論理学でいう「述語」(predicate)のような役目をする特殊な値オブジェクトを導入する。これがすなわち仕様である。仕様は一般に、次の3つを規定する。

  1. オブジェクトの妥当性検証(validation)
  2. オブジェクトの選別条件(selection)
  3. オブジェクトの生成条件(creation)

しなやかな設計 ― 理解の容易な抽象化

「しなやかな設計」の要点は、抽象化と分割の2つです。抽象化において大事なことは、モデルを見ただけでその振る舞いが容易に理解できるようにし、カプセル化の価値を最大限に高めることです。

● Intention-Revealing Interfaces(意図の明白なインタフェース)パターン

オブジェクトの内部実装を見なければ正確な使い方が分からないようでは、カプセル化が正しく機能しているとは言えない。意図が分かりにくければ、誤った使い方を誘発することにもなる。クラスやメソッドの名前というのは、開発者同士がコミュニケーションするための絶好の場所である。クラスやメソッドには、どういう方法で実装されているかでなく、その意図を示した名前を付けること。その名前が、ドメインモデルのユビキタス言語に従うようにする。テストファーストを実践して、常にクラスを使う側の視点で考えるようにする。

● Side-Effect-Free Functions(副作用の無い関数)パターン

様々な副作用*5のあるメソッドを組み合わせてしまうと、どこでどんな影響が発生するか予測できなくなるため、プログラムの振る舞いを理解することが極端に難しくなってしまう。そのため、単に引数を加工して結果を返すだけのロジック部分はできる限り副作用の無い関数としてプログラム化し、実際に状態を変化させる操作(コマンド)を最小限に留める。副作用の無い関数同士ならば、組み合わせて使っても何が起こるか予測できなくなることはない。副作用の無い関数はまた、テストも容易である。値オブジェクトは状態が変わらないので、値オブジェクトがもつ振る舞いには基本的に副作用が無い。1メソッドだけでは表現できない複雑なロジックの場合は、値オブジェクトにそのロジックをもたせることで、そこに副作用が無いこと示すこともできる。

*5 メソッド呼び出しによって、オブジェクトの状態が変化することを「副作用」と言います。オブジェクト指向の計算モデルは、本来このメソッド呼び出し(メッセージ送信)で生じる副作用によって計算を行なうモデルとして定式化されます。

● Assertions(表明)パターン

副作用の無い関数を使えば、ドメインモデル上で副作用の無い部分を分離できるが、それでも副作用のある操作は必ずどこかで必要になる。副作用のある操作を理解しやすい形で表現するには、表明(アサーション)を使って、操作の結果として何が保証されるかという事後条件(post-condition)と、操作の前後で変わらないものは何かという不変項(invariant)とを、明示的に示す。表明の仕組みがサポートされていないプログラミング言語を使っているときは、単体テストを書くことで同様のことが実現できる。ドキュメントや図に表明を記入することも重要である。

(表明の考え方は、第II部で触れたMeyerの「契約による設計」が基礎になっている)

しなやかな設計 ― 適切な分割

「しなやかな設計」のもう1つの要点である、分割についての指針です。ここで重要なことは、適切な粒度の選択と依存関係を極力排除することによって、変更のコストを低減することにあります。

● Conceptual Contours(概念の輪郭)パターン

オブジェクトの粒度に関する話。オブジェクトの粒度は、むやみに細かくしたり粗くしたりすればいい訳ではない。ドメインにはいくつもの概念が隠されていて、それら凝集度の高い概念群の間には目に見えない境界線、つまり概念の輪郭が存在する。モデルのリファクタリングを何度も繰り返すことで概念の輪郭を見つけ出し、オブジェクトの粒度がその輪郭に沿うようにする。これが、ドメインモデリングにおける高凝集のガイドラインである。

(より一般的なオブジェクト指向設計における高凝集の考え方は、第II部で触れたLarmanのGRASPパターンの中で「High Cohesionパターン」としてまとめられている)

● Standalone Classes(独立したクラス群)パターン

人間の頭が一度に考えられる概念の量には、限界がある。ドメインモデルを分かり易くするには、一度に考えなければならない概念の量を絞って、メンタルな負荷の少ないモデルにする必要がある。モデルを構成するクラスのまとまりから、関係のないクラスへの依存関係を極力排除していき、その中だけで独立して理解できる小さな世界を構築しなければならない。これが、ドメインモデリングにおける低結合のガイドラインである。

(より一般的なオブジェクト指向設計における低結合の考え方は、第II部で触れたLarmanのGRASPパターンの中で「Low Couplingパターン」としてまとめられている)

● Closures of Operations(閉じた操作)パターン

ほとんどのオブジェクトの操作は、引数や戻り値の型がプリミティブ型には収まらないことが多い。操作の引数や戻り値に新しいクラスが登場すると、それは新たな依存関係の導入になる。そうした問題を回避するために、操作の結果が、その引数と同じ型のオブジェクトを返すような操作(閉じた操作)の導入を検討する。ここで言う「閉じている」(closed)とは、数学の「自然数は足し算に対して閉じている」、つまりどんな自然数同士を足し合わせても結果はまた自然数になる、という意味と同じ。閉じた操作は、引数と戻り値が同じ型になるので、そこに余計な概念(クラス)を呼び込まなくてすむ。アイデンティティをもつオブジェクトに対して閉じた操作を適用するのは難しいため、ほとんどの場合、閉じた操作は値オブジェクトに対する操作となる。

(似ているけれども異なる概念に、FowlerとEvansが提唱している「流暢なインタフェース」(fluent interface)というものがある。こちらは、メソッド呼び出しの戻り値にさらにメソッド呼び出しをつなげて、文章が流れるようにプログラムを書けるインタフェースの設計テクニックである)

[補足] DDDとデザインパターン

前回はアナリシスパターンとの関連について触れましたが、今度はデザインパターンとの関連について考えてみます。「デザインパターンは純粋に技術的なオブジェクト設計に関するパターンなので、DDDとは関係がないのではないか」というのは、確かにその通りです。アナリシスパターンとは違い、デザインパターンはドメインに関するノウハウを提供するものではありません。

しかし「見方を変える」ことによって、DDDパターンとして利用できるデザインパターンがいくつかあります。なぜなら、概念的な領域の中にも、技術的なオブジェクト設計に見られる構造と同じような構造が発見できるからです。デザインパターンを「概念の構造を示したもの」と読み換えることで、DDDの文脈で使えるようになる訳です。

たとえばStrategyパターンやCompositeパターンは、DDDパターンとして使えるものです。Strategyパターンは、本来は「アルゴリズム」の差し替えを容易にするための設計方法ですが、ドメインモデリングにおいては「プロセス」や「ポリシー」といった概念を表現するのに利用できます。Compositeパターンは、オブジェクトを入れ子構造に設計するためのものですが、ドメインモデリングでは入れ子になった概念を表すために使うことができます。一方でFlyweightパターンのように、純粋に実装上の選択肢を示すだけで、DDDには全く適用できないものもあります。

著者自身も認めているように、どのデザインパターンがドメインにも適用できるのかは、まだ本格的に調べ尽くされた訳ではありません。どのデザインパターンがDDDで使えるのか、読者の皆さんがぜひ開拓していってみて下さい。デザインパターンがDDDパターンとして使えるかを見分ける唯一の判断基準は、パターンが「技術的な問題に技術的な解決法を提供するだけでなく、概念ドメインに対しても何かを示唆しているか」という点だけです。

IV. Strategic Design(戦略的デザイン)

第IV部では、EAIやSOAのようにシステム間の連携を必要としたり、スコープが広大で複数ドメインをまたがったりするようなソフトウェア開発のプロジェクトが対象となります。このような大規模プロジェクトは、企業情報システムの全体構造(EA)に深く関係するため、経営戦略的な視点が求められます。

DDDは、こうした高いレベルにおいても、ドメイン知識を深く反映したシステムこそがビジネスに大きな価値をもたらすという信念を忘れません。ドメインモデル(企業全体のモデル)とそれを実現する個々の実装システム(レガシーシステムやパッケージ製品を含む)とを緊密に対応付け、ビジネス側と技術チームとが互いに理解しあえる共通のユビキタス言語を作り出す、という基本原則をあくまで貫いています。

DDDの「戦略的デザイン」は、以下の3つで構成されています。

コンテキスト ― 他システムとの統合

EAIやSOAのように複数のアプリケーションが連携するようなプロジェクトでは、異なるドメインモデル間の不整合が大きな問題となります。たとえば顧客に対する請求のシステムとビジネスパートナーへの支払いを管理するシステムとでは、同じ「請求」(Charge)という概念でもその意味するところは全く異なります。それを混同してしまうのは、致命的なバグに繋がります。そのため、いかにして各アプリケーションがもつドメインモデルの一貫性を保つかが、最大の課題となります。

DDDでは、ドメインモデルの有効範囲となる「コンテキスト」を考えます。以下に登場する10パターンは、プロジェクトにどんなコンテキストが関与するかを明らかにし、コンテキスト間の関係を整理しつつその境界を維持することによって、ドメインモデルの一貫性を保ちます。

コンテキストの境界を定める

ドメインモデルの一貫性を保つために、コンテキストを維持する基本的な方法を示します。

● Bounded Context(コンテキスト境界)パターン

いくつかのビジネス領域にまたがる大規模な開発プロジェクトでは、それぞれ異なった複数のドメインモデルが並存することになる。本来ドメインモデルが異なるものを無理やり1つのコードベースで表そうとすると、当然無理が生じる。また、チーム内でのコミュニケーションも破綻する。そのため、ドメインモデルの適用可能な範囲(コンテキスト)をはっきり定める必要がある。コンテキストは、チーム編成、アプリケーションのユースケース、コードベースやデータベース(DB)スキーマに沿って、その境界線を引く。コンテキスト境界の中でドメインモデルの一貫性を保ち、境界の外から干渉されないようにする。

● Continuous Integration(継続的な統合)パターン

コンテキスト境界内でも、複数の人間が作業をしていると、次第にドメインモデルは崩れていく。ドメインモデルの一貫性を維持するために、継続的な統合を実践する。つまり、同一コンテキスト内の全コードをマージし、自動テストによりその整合性をチェックする作業を、日々のプロセスとして実行していく。

(「継続的な統合」はエクストリームプログラミング(XP)の実践の1つでもあるが、DDDではコードの統合以上に「概念の統合」に力点が置かれている)

● Context Map(コンテキストマップ)パターン

コンテキスト境界を設定し、その中で一貫したドメインモデルが維持できたら、今度はもっと大きな全体像を把握するために(非OOなレガシーシステムを含む)コンテキスト間の対応関係を明確にする。各コンテキストには、チームのユビキタス言語となるような名前を付ける。それから、あるコンテキストのモデルが別のコンテキストのどのモデルに対応するか、というモデル間の変換マップを考える。システム間連携においては、アプリケーション毎にドメインモデルが全く異なっているのがほとんどなので、コンテキストマップをしっかり作っておくことが重要になる。

コンテキスト間の6つの関係

コンテキストマップに登場するコンテキスト間の関係には、次の6種類があります。

● Shared Kernel(共有カーネル)パターン

互いに関連しあう複数のコンテキストを別々のチームで開発しているときに、わざわざ苦労してモデルの変換層を用意しコンテキストの自立性を保つよりも、モデルの一部を直接共有してしまう方が現実的なこともある。共有される核(カーネル)の部分には、ドメインモデル、ソースコード、DBスキーマなどが含まれる。コンテキスト内ほど頻繁でなくてもいいが、カーネルを共有する複数コンテキストをまとめて、定期的に継続的な統合を実施すること。共有カーネルは特別な部分になるため、他チームへの相談なしに勝手に変更を加えてはならない。

● Customer/Supplier Development Teams(顧客/供給者の開発チーム)パターン

コンテキスト境界の分かれた2システム間の関係が、一方が他方を利用する形になっていることがある。その場合、各チームの役割は必然的に異なったものとなるので、両者の運営を円滑にするために、2チーム間に顧客(使う側)と供給者(使われる側)の関係を導入する。供給チームは顧客チームに対して、実際に交渉や見積もりを行なう。供給チーム側のシステム修正を容易にするため、受け入れテストを供給チーム側の継続的な統合に組み入れる。

● Conformist(順応者)パターン

使われる側のチームが力を持っている場合など、主に政治的な理由で顧客/供給者の関係がうまく構築できないこともある。そのときはコンテキスト境界を固持せずに、あえて使われる側のドメインモデル(ユビキタス言語)に隷属的に従うという選択肢もある。当然、使う側では理想的なドメインモデルを設計できなくなるが、その代償としてアプリケーション統合が劇的に簡単になる。

● Anticorruption Layer(腐敗防止層)パターン

新規に構築するアプリケーションも、たいていはレガシーなど既存の外部システムと連携しなければならない。既存システムが持つドメインモデルは、これから構築しようとする新しいドメインモデルにはそぐわないことが多い。両者のモデルの対応付けが容易でない場合は、新システムと既存システムとの間に隔離層(腐敗防止層)を設けて、そこで両方向に対するモデルの変換を実装して両者のモデルを完全に独立させてしまう。ただし、腐敗防止層の構築には大きなコストがかかるので注意。

● Separate Ways(別々の道)パターン

もし2つのアプリケーションがほとんど機能を共有しておらず、統合することにメリットがないのであれば、無理して統合せずに互いに無関係な別々のコンテキストとして開発していった方がいい。

● Open Host Service(公開ホストサービス)パターン

あるアプリケーションが他の多くのアプリケーションから利用されるような場合は、1つ1つについて変換層を用意するような面倒をせず、プロトコルが公開された共有サービスの形にする。サービスの機能を拡張したいときは、プロトコルを拡張していく。

補足的なパターン

コンテキスト間の関係を構築する際に、次のような補足的なパターンを用いることもできます。

● Published Language(公表された言語)パターン

コンテキスト間連携の通信媒体として、共通の情報モデルを定めたいことがある。しかし、既存の自家製ドメインモデルでは不適切なことが多い。モデルが未成熟だったり、無駄に複雑だったり、あるいは文書化されていなかったりするためだ。そのようなときは、きちんと文書化されていて広く周知された共有言語を採用するのがよい。

蒸留 ― 抽象化の方法

コンテキストによって一貫性あるドメインモデルを維持できたとしても、複数ドメインが関与する複雑なプロジェクトからビジネスに重要な本質部分を見抜くことは容易ではありません。競争力の源泉となるようなエンタープライズシステムを構築するには、ドメインに適切な抽象度を与えて、ビジネスにとって本当に重要な部分にフォーカスして資源を投入していかなければなりません。

DDDでは7つのパターンによって、広大なシステムから本質部分を「蒸留」(distill)するノウハウを示します。*1「蒸留」パターンは、開発上の優先度を示すとともに、アウトソースやオフショア開発、パッケージ製品の導入などの戦略上の決定をする際の指針にもなるものです。

*1 蒸留とはもともと化学用語で、複数の物質が混じり合った混合物を蒸発させることによって、特定の化学成分だけを濃縮する操作のことです。ちなみに、Eric Evansは化学工学の修士号をもっているそうです。

ドメインの優先順位付け

エンタープライズシステムの本質部分を見つけるには、ドメインを「中核ドメイン」と「汎用サブドメイン」の2つに分類し、優先順位を明確にします。

● Core Domain(中核ドメイン)パターン

巨大なシステムでは、複数の異なるドメインモデルが並存する。すべてのドメインで完璧なモデルを構築することは不可能なので、優先順位を付けて、ビジネスにとって最も影響力のある重要なドメイン(中核ドメイン)にフォーカスする。中核ドメインに最も優秀な人材を投入し、経営資源を注ぎ込む。中核ドメインの資産価値を最大化しつつ、他の周辺ドメインは中核ドメインへの貢献度によりその投資対効果(ROI)を評価していく。*2

*2 他のパターンの多くが複数形「〜s」で名付けられているのに対し、中核ドメインパターンが単数形なのは、おそらく中核は本来システム中に1つしかないものだからでしょう。

● Generic Subdomains(汎用サブドメイン)パターン

ドメインの中には、ビジネス上の差別化要因とならない汎用的な機能を提供するだけのものがある。そうしたドメインはサブドメインとして中核ドメインからは区別し、開発上の優先度を低く設定する。汎用サブドメインから深いドメイン知識が得られることは稀なので、優秀な人材をそこに投入してはならない。汎用サブドメインの構築には、以下の4つの選択肢がある。

  1. パッケージ製品を導入する
  2. 公表されたモデル(アナリシスパターンなど)を流用する
  3. 開発をアウトソースする
  4. 自社で開発する

中核ドメインの文書化

中核を見出したら、今度はそれを見失わないようにドキュメント化します。

● Domain Vision Statement(ドメインビジョン声明文)パターン

中核ドメインでは、プロジェクト開始時に1ページほどの「ドメインビジョン声明文」を用意する。声明文とは、ドメインの説明と、ドメインがビジネスにもたらす価値(バリュー・プロポジション)とを簡潔に書いたもの。記述はなるべく簡潔に努め、新たな知見を得るたびにきちんと改訂していく。声明文を用意することの意義は、プロジェクトのことを詳しく知らなくても、誰もが一目でそのドメインの価値を理解できるようにすることにある。

● Highlighted Core(中核のハイライト)パターン

ドメインビジョン声明文中核ドメインの価値をすぐさま理解するのに重要だが、ドメインをもう少し詳しく理解したいときには別のドキュメントが必要になる。「中核のハイライト」は中核ドメインの構成要素が何であるかを示し、人によって中核ドメインの理解がブレないようにするためのドキュメントである。中核ハイライトの書き方には、次の2つのアプローチがある。

  1. 中核ドメイン(構成要素とその相互関係)を簡潔に記述した、3〜7ページの軽いドキュメントを用意する
  2. プロジェクトのモデル全体を記述した正式な設計ドキュメント上で、中核ドメインの構成要素となるモデルに単に印を付けていく

中核を磨き上げる

優先順位付けにより抽出された中核も、そのままでは本質と関係のない不純物が混ざっていたり、まだドメインが複雑すぎることがあります。ドメインリファクタリングによって、中核をさらに中核的なものへと磨き上げていく必要があります。

● Cohesive Mechanisms(凝集されたメカニズム)パターン

中核ドメイン汎用サブドメインはドメインモデルの中で注目すべきものとそうでないものとを分けるためのパターンだが、ドメインモデル(What)と実現のためのメカニズム(How)とを分離することも必要になる。概念的にまとまりのあるメカニズムを、軽量なフレームワークの形にしてドメインから分離する。フレームワークのインタフェースには意図の明白なインタフェースパターンを採用し、ビジネス上の問題とテクニカルな解決法とを明確に切り分ける。こうすることで、ドメインはより宣言的(declarative)なスタイルになっていく。汎用サブドメインはドメイン上の汎用部分を抽出するパターンなのに対し、凝集されたメカニズムはソリューションの汎用部分を抽出するパターンと言える。

● Segregated Core(中核の隔離)パターン

中核ドメインの中から、さらに本質と関係のない付随的な部分を汎用サブドメインの方へ移していく。ドメインリファクタリングを施し、本質的な概念だけからなる純粋なモデルになるよう中核を隔離していく。分割によって中核を磨き上げる方法。

● Abstract Core(中核の抽象化)パターン

中核ドメインが複数のモジュールで構成され、モジュール間に複雑な相互作用があるような場合、各モジュール内のキープレイヤーを(抽象クラス/インタフェースによって)抽象化したモデルを作り、それを新しい1つのモジュールにまとめる。このモジュール内のモデルは、複数モジュール間の相互作用を抽象化して全体像をまとめたものになる。そして、これが新しい中核のモデルとなる。抽象化によって中核を磨き上げる方法。

大規模な構造 ― 「大きな絵」の共有

コンテキスト蒸留により、統合システム間の関係を把握し、システムの本質部分にフォーカスすることが可能となりますが、それだけでは大規模なシステムが全体としてどんなストーリーをもっているかを理解することはできません。大規模システムの構築を成功させるには、チーム内のメンバやチーム間でアーキテクチャレベルの「大きな絵」を共有し、同じ目標意識をもって協調していくことが肝心です。

DDDは最後に、概念レベルの大規模な構造を扱うための5つのパターンを示します。ただし、著者自身も認めているように、「大規模な構造」をパターンにまとめる試みはまだ始まったばかりであり、DDDが現時点で提供できるノウハウも部分的なものに過ぎません。「大規模な構造」のパターンは、今後さらなる成熟が求められる分野でもあります。

大規模な構造を扱う際の基本思想

大規模な構造を設計する場合には、経験則から、まず始めに受け入れなければならない基本的な考え方があります。

● Evolving Order(進化する秩序)パターン

すべての要件を満足する大規模な概念構造を、一度に設計することは不可能だ。アプリケーションを作りながら、少しずつ構造を進化させていくのがよい。進化の過程で、以前とまったく異なる構造に変化していくことも稀ではない。大規模な構造はコンテキストマップと違い必須のものではないため、誤った構造を作り込んでしまう位なら何も構造を定めない方がよい。したがって、常に必要最小限のシンプルな構造を探し求めること。

大規模な構造の3例

DDDが現時点で提供できる大規模な構造のパターンには、以下の3つがあります。

● System Metaphor(システムのメタファ)パターン

比喩(メタファ)を使うことが、システムアーキテクチャの理解に有効なことがある。その場合は、チームにメタファを浸透させ、ユビキタス言語に取り込む。しかしメタファとは本来大雑把で不正確なものなので、不適切なメタファを使うとチームを誤った方向に導いてしまう。メタファを使う場合は、それが本当に適切かどうかを継続的に検証しつづけなければならない。システムの開発が進むにつれてメタファが適切でなくなってきたら、メタファを捨て去る勇気を持たなければならない。

(XPの実践の1つである「システムのメタファ」と同じものである)

● Responsibility Layers(責務の階層)パターン

オブジェクト指向設計では、各オブジェクトを責務の割り当てに基づいて設計する責務駆動設計(Responsibility Driven Design, RDD) が基本だが、RDDは大規模な構造に対しても適用可能だ。大規模な構造においては、アーキテクチャパターンのLayersパターンを責務の構造にも適用し、システム全体にまたがった「責務の階層構造」を考える。階層構造では、上位層は下位層に依存するが、下位層は上位層からは独立している。責務の階層は、システムの高次元の目的や設計を物語り、ドメインモデル設計のガイドラインとなる。責務の階層の一例を示すと、以下のようなものになる。

  • 意思決定(decision)層 … どんな戦略やポリシーを実行すべきかを決定する層
  • ポリシー(policy)層 … 戦略上のゴールや業務ルールを実際に適用する層
  • 運用(operation)層 … 日常行なわれている業務を表す層
  • 業務基盤(capability)層 … どんなリソースがあり、業務上なにが可能なのかを表す層

● Knowledge Level(知識レベル)パターン

アナリシスパターンには、オブジェクトを「運用レベル」(operational level)*3と「知識レベル」(knowledge level)に分けるパターンがある。この考え方は、大規模な構造を設計する場合にも適用できる。知識レベルのモデルは、運用レベルのドメインモデルについてのルールや知識を規定する。知識レベルは一見「責務の階層」の一例のようにも思えるが、知識レベルと運用レベルの間には双方向の依存関係が許容される点が異なる(責務の階層では下位層は上位層からは独立している)。

(知識レベルとは「モデルについてのモデル」のことなので、アーキテクチャパターンのReflectionパターンをドメインモデルに適用したケースと捉えることもできる)

*3 「操作レベル」という訳の方が有名ですが、知識(knowledge)との対比で "operation" を使うときは、法体系や業務ルール、経営上の意思決定に対して、それを実際に適用し実施するという意味合いが強いと思い、あえて「運用レベル」という訳語を充てました。ビジネスの世界でよく使われる operation という言葉には、たとえば運用部門(operational department)や、企業の最高意思決定者であるCEOとの対比で最高業務責任者(Chief Operating Officer、COO)などがあります。「知識」との対比が分かりにくい「操作」よりも、概念上の決まりごと(知識)を実行に移すという意味で「運用」と訳した方が、2つのレベルの違いがイメージし易いのではないかと私は考えています。

DDDの最終形態

ドメインモデル開発の成功を繰り返し経験した幸運なプロジェクトが、稀に到達することのできるDDDの桃源郷があります。

● Pluggable Component Framework(着脱可能コンポーネントのフレームワーク)パターン

あるドメインで何度かDDDを成功させ、ドメインへの深い理解へと到達していくと、そのドメインに特化したドメインフレームワークを設計できることがある。ドメインフレームワークとは、中核の抽象化により抽出されたドメインの中心的なインタフェースと相互作用から構成される中央ハブのようなもので、そこにドメインの可変部分をコンポーネントとして着脱できる。ただし、ドメインフレームワークには、(1) 実現が非常に難しい、(2) フレームワークが提供する中核ドメインにアプリケーションが縛られる、などの欠点もある。

(半導体製造ドメインで「着脱可能コンポーネントのフレームワーク」の構築を試みた例に、Mohamed FayadとRalph JohnsonのSEMATECH CIMフレームワークがある)

[コラム] 戦略的DDDをエンタープライズアーキテクチャに適用した事例

DDDの「戦略的デザイン」パターンは企業の経営戦略レベルに適用できるとは言っても、具体例がないとなかなかイメージしにくいと思います。DDDの公式サイトにて、エンタープライズアーキテクチャ(EA)の改善に「戦略的デザイン」パターンを適用した、ノルウェーの大手石油/ガス会社StatOil社の事例が紹介されています。*4

StatOil社では、原油・精油・液化天然ガス(LNG)を扱うサプライチェーンのビジネスプロセスにEAを適用して、IT投資への戦略を練っています。この事例では、EAの論理的なアーキテクチャと、それを実現する物理的なソフトウェアアーキテクチャとのギャップを埋めるのにDDDを適用しました。事例には、「(資源の)供給業務」「請求業務」「取引業務」「通信ゲートウェイ」「輸送と配給」「フロント画面」「フォルダ」「文書ストレージ」の8つのコンテキストが登場します。この大規模なエンタープライズシステムに対して、戦略的デザインの3要素「コンテキスト」「蒸留」「大規模な構造」を適用し、評価しています。

「コンテキスト」の適用では、上記の8コンテキストからコンテキストマップを作成し、コンテキスト間の関係を顧客/供給者共有カーネル公開ホストサービス腐敗防止層の4パターンに分類して整理します。「蒸留」の適用では、各コンテキストを中核ドメイン汎用サブドメインに分類し、開発上の優先順位を定めます。「大規模な構造」の適用では、責務の階層を導入してコンテキストを階層毎に分け、各コンテキストの担当者が担うべき役割を明確化します。

適用結果は、以下のようにまとめられています。

コンテキスト
コンテキストマップおよびマッピングの過程で得られた知見が、EAの中で新規プロジェクトのスコープを決定するのに大いに役立った。また、既存のソフトウェアアーキテクチャの改善にも貢献した。
蒸留
中核ドメインの特定が、開発資源を分配する指針の決定や、開発中のソフトウェアがどんな目的をもっているかを開発者自身が理解するのに役立つと思われた。しかし、そのためにはどのドメインが最も重要かについて、ビジネス側の合意を得なければいけない。これは困難で、ビジネス側にも熟練を要求する作業だった。
大規模な構造
責務の階層の適用が、当事者間のコミュニケーションの促進に役立つと思われた。しかしそのためには、責務の階層が定める責任範囲へのコミットを、ビジネス側から得なければならないというハードルがあった。

このレポートの結論は、コンテキストマップはすぐにでもEAの改善に役立つが、蒸留および責務の階層については、有望な考え方ながらもビジネス側の努力も必要となるため手軽には導入できなかった、とのことでした。

なお今回は紹介しませんが、同じくStatOil社の事例として、ERPなどの商用パッケージ製品の評価に「戦略的デザイン」パターンを適用した事例も紹介されています。こちらの事例では、コンテキストマップと責務の階層の組み合わせが、パッケージ製品の評価に不可欠な暗黙知の顕在化に役立ったと報告されています。

*4 この事例紹介は、2006年のOOPSLA(Object-Oriented Programming, Systems, Languages, and Applications、世界最大のオブジェクト指向国際会議)に論文として発表されたものです。なお、スカンジナビア地方(ノルウェー、スウェーデン、デンマーク)は特にオブジェクト指向が盛んらしく、Eric Evansが主催するDomain Language社の顧客にはこの地方の企業が多いそうです。