ユビキタス言語と境界付けられたコンテキストを構築する目的とは

このエントリーは、 「ドメイン駆動設計 #1 Advent Calendar 2018」の23日目の記事です。 
22日目は、[@dnskimo@github](https://qiita.com/dnskimo@github) さんの「[集約とトランザクション境界に関するメモ](https://dnskimox.hateblo.jp/entry/2018/12/22/154038)」でした。 

# はじめに
この記事は以下の書籍から数多く引用しています。この記事を読んで興味をもたれた方は併せてご覧頂ければと思います。 

- [エリック・エヴァンスのドメイン駆動設計](https://www.amazon.co.jp/dp/B00GRKD6XU)
- [.NETのエンタープライズアプリケーションアーキテクチャ第2版](https://www.amazon.co.jp/dp/B00ZQZ8JNE)

# TL,DR
- ドメイン駆動設計におけるドメインとは、あるシステムにおける領土・分野のこと
- ユビキタス言語とは、ある目的に添った、ステークホルダ間での共通理解に必要な言葉の『最も小さな粒度である単語』のこと
- 境界付けられたコンテキストとは、あるシステム境界におけるドメインにおいて『ユビキタス言語を元に構築された文脈（コンテキスト）』のこと
- 概念モデルとは、境界付けられたコンテキスト内部でユビキタス言語によって構築される「物事」「考え」「対象」「現象」の本質を抽出して単純化した構造のこと
    - 本質的に全てのモデルは間違っているが、中には役に立つ物もある。 - George E.P. Box

# 『ソフトウェアの核心にある複雑さに立ち向かう』とは 
　ドメイン駆動設計は、_Eric Evans_が発表したソフトウェア設計と開発に対するアプローチです。同書の副題は、『__ソフトウェアの核心にある複雑さに立ち向かう__』となっています。さて、ソフトウェアの複雑さとは何を指すのでしょうか？ 
　筆者にとってのソフトウェアの複雑さとは、ソフトウェア開発を取り巻く周辺環境（プロジェクト管理、設計、実装、運用など）において、
『__何もしなければ、エントロピー増大の法則により秩序から無秩序へと進んだ先にある、無秩序な状態__』であると考えています。
無秩序なソフトウェア開発の現場では、システムを熟知しているエンジニアの退職などで全貌の把握が不可能となったり、品質担保のための__管理工数の増大__・__モチベーションの低下__・__コストの増大__・__納期の遅れ__などが発生する可能性が高いことが否定できません。
　筆者の考えるドメイン駆動設計の『複雑さに立ち向かう』理由は、ドメイン駆動設計を利用した現場で利用されることの多いアジャイル開発（プロジェクトマネージメント手法）で定義される『__予算__』『__時間__』『__品質__』『__スコープ__』の4点のトレードオフ要素が、__各々トレードオフがありながらも全ての要素が良い方向に向かわせて、結果として秩序立てた状態とすることです。__
__トレードオフの取捨選択__（トレードオフスライダーと呼ばれます）は選択と集中のための手段ですが、プロジェクトを運営する上で『__品質__』も『__スコープ__』も『__時間__』も__犠牲にできない__という場合（『予算』は外的要因が多いため除外しています）に、__可能な限り各要素を最大化を目指す為の手段である__と言えます。
　ドメイン駆動設計における『複雑さに立ち向かう』ために必要な要素として、平易で簡潔な言葉で説明が可能となる『__ユビキタス言語__』と、ユビキタス言語により構築された機能その物である『__境界付けられたコンテキスト__』を関係者間で築き上げ、__全関係者が納得できる形で『概念モデル』を完成することがゴール__です。

# 『ドメイン駆動設計における分析』とは
　ドメイン駆動設計における分析とは、__『ユビキタス言語』の構築__と__『境界付けられたコンテキスト』の構築__の2点が挙げられます。
　ユビキタス言語とは、ある目的に添った、ステークホルダ間での__共通理解に必要な言葉の『最も小さな粒度である単語』__です。
たとえば、筆者の本業である[レシピ動画メディア]
(https://delishkitchen.tv/)では、『レシピ（料理）』『キュレーション（配信用レシピのバルクで「本日のオススメ」などの一セット）』『フライヤー（チラシ）』などがその代表例です。
これらの単語は、たまたま自然言語と一致して分かりやすい物となっていますが、組織内でしか通じない言葉となることも希ではありません。
　境界付けられたコンテキストとは、あるシステム境界におけるドメインにおいて__『ユビキタス言語を元に構築された文脈（コンテキスト）』__です。 
境界付けられたコンテキストは、よりドメインの範囲の広いユビキタス言語であり、例えば『リテール（小売り）』や『プレミアム（特別性の高い課金）』などがあげられます。
　実際のビジネスにおけるソフトウェアの利用はビジネスの活動の全体においてその一部であり、ビジネスドメインにおける本質的な関心事は__ソフトウェアが生み出した成果（売上げなど）__を指すことが多く、ソフトウェアそのものには関心が低い場合が多いです。 
ソフトウェアエンジニアとしては、ビジネスの専門家がシステムそのものに関心が低い場合があることを理解しながらも、__関係者を巻き込んで『ユビキタス言語』と『境界づけられたコンテキスト』の構築を進めること__を理解しておく必要があるでしょう。
## ユビキタス言語を構築する目的
　_Eric Evans_は、ソフトウェア開発者がドメインエキスパートやユーザーなどの関係者と会話する場合、いかなる場合においても__誤解のリスクを緩和する__ため共通理解が可能な、なるべく平易で簡潔な言葉（単語）を用いて、__システムに関わる関係者間__で誤解が発生しないように努めることを推奨しました。
この言葉は共通知識や言語として組織内に浸透することから、__ユビキタス[至る所にある、遍在する、至る所に姿を現わす]な言葉__となり、__ユビキタス言語__と呼ばれることとなりました。
　ユビキタス言語は一度決まったらそのままではなく、ドメインに関連する知識が深まるに都度、__徐々に変化して進化する__可能性があります。もしユビキタス言語の進化が発生した場合は、該当のユビキタス言語を用いたコーディング規約やコードと同期してリファクタリング対象となり、__システムへの理解がさらに深まる事につながります__。
　ユビキタス言語を構築する意義とは、仕様策定の会議体・設計・コードそのものなどの全ておいてに、遍在的に（ユビキタス）に現れることで、__組織内の人員のシステムに対する共通理解を深めることが目的__です。 

## 境界付けられたコンテキストを構築する目的
　境界付けられたコンテキストとは、システム相互作用における境界が定義された物を指し、実際のプロジェクトでは__『縄張り』__のような物です。境界付けられたコンテキスト内の各コンテキストはユビキタス言語の一つとして構築されて命名されることになります。
　ビジネスドメイン（ビジネス領域）の世界では、さまざまなサブドメインに比較的簡単に分割されることがありますが、ソフトウェア開発におけるドメインは、機能や概念が重複せずに簡単にサブドメインに分割できるケースは多くありません。
各コンテキストの境界を定義して、その内部のコンテキストがどのように扱うかを、図を書く作業は__コンテキストマッピング__と呼ばれます。
コンテキストマッピングをすることにより、__ビジネスドメインにおける責任範囲の分離に役立つ__ことがあります。本質的にはビジネスドメインとソフトウェア開発のドメインは表裏一体であるのですが、とあるシステムで機能系とレポート系があったときに、機能系はソフトウェアドメインとビジネスドメインを比較的簡単に分離できるのに対して、レポート系はビジネスドメインで分離が難しいことが多いです。
これはレポート系が各ビジネスドメインのデータを集約して、まとめた結果をレポートや帳票として出力する必要があるためです。従ってレポート系は本当に境界づけられたコンテキストとして分離する必要があるのか、よく考慮して設計する必要があります。
　境界付けられたコンテキストにより定義された各コンテキストは、実際の企業内の__物理的な組織を反映していること__がよくあります。
これは[コンウェイの法則](https://ja.wikipedia.org/wiki/%E3%83%A1%E3%83%AB%E3%83%B4%E3%82%A3%E3%83%B3%E3%83%BB%E3%82%B3%E3%83%B3%E3%82%A6%E3%82%A7%E3%82%A4)と呼ばれており、コンテキスト内部の名前がユビキタス言語となり、ユビキタス言語がチーム名となることがあります。
ソフトウェアは__最終的には企業内の組織構造に反映される__ことから、__コンテキストマップに企業の組織図を反映させるべきである__という考えがあります。しかしながら筆者の経験では、__コンテキストマップをそのまま企業の組織図に当てはめることはスムーズにいかないことが多く、組織構造の変更がソフトウェアの構造変更よりも苦難が大きいことが原因である__と考えられます。
　近年ではコンウェイの法則を逆手に取った、[逆コンウェイ戦略](https://anagileway.com/2016/05/25/inverse-conway-maneuver-and-devops-microservices-and-agile/)と呼ばれる考え方が出現しています。これは組織体にソフトウェアを当てはめるのではなく、逆に__戦略的に組織構造をソフトウェアに反映させる__ことで、__ビジネスの方向性とシステムの方向性を一致させて組織内コミュニケーションのAgility（俊敏性）を高める戦略__です。
従って境界付けられたコンテキストを定義する目的とは、__各組織体のチーム編成を適切な設計境界により行うこと__で、各チームが自分に与えられたコンテキストに__『縄張り意識』を持つこと__が、チーム内外の人員に対する__責任感__やチーム内の__一体感__を生み、__人と情報の流れを円滑とすること__がゴールとなります。 
　近年の大規模システムを構築する際によく取られる手法である[マイクロサービス](https://en.wikipedia.org/wiki/Microservices)は、境界付けられたコンテキストの境界の定義を適切に進めることで、__成功確率が高い大規模サービスを作る手段__と言っても差し支えありません。
組織内の文化にもよりますが、一度境界づけられたコンテキストが決定されると、ソフトウェアの価値基準の戦略的な見直しが発生しなければ境界づけられたコンテキストそのものの変更が発生しないことが多いようです。

# まとめ
ここまで読んでいただきありがとうございました。 
『__ソフトウェア開発の原料は言葉である。__』という名言があります。
ドメイン駆動設計の戦略的分析で重要となる要素は、『__ユビキタス言語__』と『__境界づけられたコンテキスト__』の二点の構築が必要であると述べました。これらはソフトウェア開発の現場で生物のように有機的な変化や進化をしながら構築されていく物です。このトピックを読んでくれた方が、より具体的で実践的なユビキタス言語と境界付けられたコンテキストを構築する助けになったら幸いです。 
　24日目は、[@j5ik2o](https://qiita.com/j5ik2o) です。お楽しみに！

# 補足
実際にどのように『ユビキタス言語』と『境界づけられたコンテキスト』が構築されるのか拙筆スライドも併せてご覧ください。

エンジニアのためのドメイン駆動設計実践入門 / DDD for Engineer newbie
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">DDDの資料です。<a href="https://t.co/o9d8m3a9go">https://t.co/o9d8m3a9go</a></p>&mdash; masa (@smdmts) <a href="https://twitter.com/smdmts/status/1032832429143154688?ref_src=twsrc%5Etfw">2018年8月24日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>