DDDモデリングに必要な本でも語られていないこと

# 内容の概要
この記事では、DDDモデリング、それもエヴァンス本などにも書かれていないけれど、
自分が実際に案件の中でDDDをビジネスサイドからやってきてみて気づいた内容になります。

データやそのデータを必要とするプロセス(ロジック)を凝集させるですとか、
プロセスをどの概念に割り当てるか？といったオブジェクト指向に必要な原則などは
以下のページで学んでいただければと思います。

https://qiita.com/Kudo_panda/items/6d4cff3dff0f7d060405

今回はそれ以外のマインドや組織体制、ビジネススキルとの組み合わせについて述べます。

# 誰向け？
モデリングにまだ慣れていない方。
具体的には、一枚絵にすべて概念を描きだしてしまって相手に見せた際、意図が伝わらなくて困っているといった方でありかつ、
モデリングは初心者だけども、いずれプロのモデラーになりたい！という方向けの内容です。

:::note warn
定期的に批判的思考を働かせ、「今のモデルって前提からして合ってるのかな？」
という検証を当たり前に行っている玄人の方は、ああそんなこと知ってるよとなる内容かもしれません。

でも待ってください。
そんな「自分を玄人」だと思っているそこのアナタも本当に常に前提条件を疑ってかかれていますか？
:::


# 私の主張と提案内容
## 主張
端的に言うと、巷で語られているドメインモデリングを本気で費用対効果の高いモデリング活動にするためには、単なるユビキタス用語集をつくるだけでは、ほぼ意味がないと感じています。

エリックエヴァンスの本を読んでいても、事例が船舶というマニアックなドメインであり、
かつアプリケーションエンジニアがドメインエキスパートと密にタッグ組んで、
継続的に改善しながらモデリングを行い、という内容にフォーカスが当てられ、
その後ろに潜んだ大事な思考プロセスはあまり巷に浸透していないと実感しています。

その理由は、以下の３つの事実が所以です。

## ３つの事実
:::note warn
モデリングをしているコミュニティで、たとえ玄人でも今んとこ誰一人として前提条件を検証するという活動をしていない
:::

:::note warn
モデリングの対象スコープをマクロに絞り込んで、どこにモデリングコストをかけるべきか？という議論をしている玄人団体にいまだほぼ出会っていない
:::

:::note warn
組織全体でDDDモデリングをする文化のある企業において、
外から見ると【どの部分において密にほかのチームとモデリングを越境して行っているか】をマネジメントできていて、その企業では無意識に当たり前にやっているがゆえに言語化されていない
:::

## 提案内容
そこで、私なりの創意工夫として、
業務の傍らの時間で、仮説思考や帰納法演繹法、制約理論、クリティカルシンキング、
副業で必要だから学んだECRS原則、
昨年度案件で必要であると判断した組織設計に関するチームトポロジー
などなどといった複数の思考を学んだことで、
それとモデリングを掛け合わせて初めてDDDモデリングができている。
むしろそれがないと、DDDやってますとは言えないと実感するようになりました。

# 必要な思考やスキル一覧

## データモデリング
関係しあったデータを１つのテーブルにまとめる、つまり高凝集なデータをまとめるスキルです。
ここにはマクロに見た組織全体のデータ群に、適切に境界を定義するスキルも含まれます。
ちなみにデータのコンテキスト境界のことを【データドメイン】と言ったりするそうです。
そのため、ここではデータドメインと呼ぶことにします。

データドメインの考え方として以下があります。

### 

## 
情報エキスパート

# モデリングをする前提活動
モデリングをする際には、マクロなコンテキストマップ図を描いた上で、
その境界内を徐々に解像度深める形で概念を洗い出していく。
実はこの前提のスコープをそろえる活動が、初学者のモデリングをする様々な場面でないがしろにされがちな印象を受けます。

この前提となる「今からこの中の概念をモデリングしますよ」という前提条件なくして、
モデリングをしてしまうと、あまりにも発散しすぎてしまい、
一枚絵で複雑な立体の形をした対象のドメインを表現した図になってしまうリスクが跳ね上がります。
実際問題、私自身もそれを何度か体験し、
「なんでレビューをお願いした際に、伝わらないんだろう？」と悪戦苦闘した日も懐かしくありません。

また大事なことなのでマーカーで目立たせると、

:::note info
一度定義した前提スコープも中身を概念モデリングで議論しているうちに、
「あれ？前提スコープずれてきてる？？」てことが往々にしてあります。

その前提スコープを概念モデリングの検証活動を通して、どれだけ再調整できるか？が大事です。
:::


## アンチパターンモデリング
実際の案件では、必ず前提条件になる前提スコープの議論は必ず行ってからドメインモデリングを洗い出していく活動をやってください。

でも普段のプライベートな練習や、バーチャルプロジェクトといったお金の発生しない場面においては、あえて前提スコープを議論しないことによるアンチパターンモデリングを身をもって体験することをお勧めします。
絶対にそのモデリングの活動の中でうまいこといかなかったり、
同じ対象を議論しているのになぜか概念や同じ用語に対する背景のそろわない場面が多発するはずです。

でもその道を通った方が、今回の記事で自分が伝えたい内容を身をもって体にしみ込ませることがより容易になると考えています。

そして同じメンバー

その理由はたとえでいうのなら、サイコロの展開図を思い描いていただきたい。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/347a4718-444a-0ab5-ee78-0743e6873a47.jpeg" width=35%>

サイコロは対称性のあるシンプルな形をしているからまだかわいいもんです。
この展開図では、各面の数字がわかるように線(境界)で区切られていますから。

でも実際ビジネスなどでモデリングする対象は、もっともっともっと複雑な形状です。
しかも目にはみえない概念要素の集合からなっている。
どこが境界の位置なのかも、ビジネスが拡大するごとにどんどんわからなくなりやすい。

その展開図を境界の位置もなく、たった１枚の図で表現されたら、
「え？どこが折り目(つまり境界の位置)ですか？」となってしまう。

その境界の位置は最初からはっきりと定義できるほどシンプルなものではない。

だけども、定義しないことにはモデリング作業が変な方向に発散しやすい。

## ここ大事な思想
だからこそまずは、いったん「ここが境界の位置であると一旦仮決めしよう」
という折り目(境界)の位置っぽいと思われる場所を仮説ベースで仮置きし、
その中でモデリングしていく。

つまり、中身を埋めていく。詳細化(解像度を上げていく)していって、
その活動の中でまた前提の境界の位置の検討をし続けることが大事である。

# 複雑なものは動かす前にスナップショットでモデリング
コアドメイン領域部分のような非常に変化にさらされるような部分に関しては、
時間経過でどんどん複雑さを増していくことが多いため、
動かしながら(追加仕様や仕様変更しながら)モデリングをするのではなく、
一回止めてモデリングをした上で動かすというようにしないとシンプルに考えられない。

## 静止させた状態でのモデリング
解像度の浅い部分は一旦静止させて(仕様変更とか入れずに)、境界の仮定をおいてモデリングを行う。
後述の演繹×批判的思考を持ちながらモデリングを行うことで、
登場する概念たちを抽出するだけでなく、仮定で置いた境界の位置の妥当性を検証しては改善をする。

境界のその現時点でのもっとも妥当な位置になったら、その静止させた状態でのモデリングは一旦完了だ。

:::note warn
ただし、この境界の位置も現時点でもっとも妥当そうと判断された位置でしかない。
:::

## 動かす！(仕様変更)
仕様変更や追加仕様をされた際に、先程定義したモデルが妥当である保証はどこにもない。
前提の範囲が広がったり、もしかしたら仕様変更されて初めて先程の静止させた状態での境界の位置が、誤りであったことが判明したりもする。

もちろん仕様変更の際に境界の位置が変わることもなく、１段階前のモデルをそのまま使うことができる場合もある。
しかしだからといって、

:::note warn

最初から１度作ったモデルをなんとしてでも再利用しようとしないこと！！
:::


## 

# 演繹法×モデリングを使った境界位置の検証
## 演繹法について
演繹法については、ネットでググるなり、以下の書籍をお読みください。
※ここではその詳細には触れません。

演繹法とは、前提の法則や仮定を仮に正しいと仮定して、
そのうえで事実をその法則に当てはめてみて、結果を推測する方法です。
もしもその結果が実際に起これば当てはめた前提条件は正しかったといえます。
逆に推測した結果と、実際の未来の結果が一致しなければ、当てはめた前提条件が誤りであったという証明にもなります。

たとえば「雨降ったら地面は濡れる」という前提法則。
これに「今雨が降っている」という事実を当てはめると、この後「地面は濡れる」
という結果を推測できます。
そして、実際に地面が濡れたら、当てはめた前提条件はあっていた(ただし現時点での話)
ということになります。

ここで大事な思想は2つに集約されます。

:::note warn
当てはめた前提条件に一致するような結果だけを採取しないこと
:::

:::note warn
実際の結果と照らし合わせて検証活動すること
:::

## 演繹法とDDDモデリングの関係性
概念モデリングで前提となる境界内の要素をいくつか出していくと、
モデリングをしていく中で徐々にその境界内の解像度が上がっていく。

丁度下図のようなイメージである。

![reso_3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/3db97f9a-f074-04fe-b538-5fa2f92ad045.jpeg)

概念モデリングをする前には、境界内の解像度が非常にあやふやな左側の状態であるが、
境界の内側をモデリングするうちに、どんどん右側に近づいていくのだ。

すると自分たちの定めた前提の境界の範囲にちょっと違和感を感じ始めることがある。
「この前提条件」という枠組みの中でモデリングをしていたけれど、
解像度が上がるうちにその枠組みからはみ出すような概念が登場することがあるのだ。

この時に無理にその前提条件である境界という枠組みに縛られなくていい。
なぜならその境界という枠はその時点で置いた仮定に過ぎないからだ。

解像度が上がってきてその前提条件がおかしいと気が付いたなら、
むしろその前提条件である仮置きで定義した境界の位置がおかしいという何よりの証明になる。

仮に前提条件である境界の位置が間違っていなければ、
絶対に１つたりともその前提からはみ出すような概念要素は登場しないからだ。

## 演繹法のアンチパターン
演繹法はこれから起こる未来の結果を予測する推論技術であると同時に、
仮定で置いた前提条件の検証をその結果から検証できる方法でもある。

この時のアンチパターンとして、その前提条件にはまるような結果のみを採取して、
一度定めた前提条件をさも正しいかのように扱ってはならないというアンチパターンがある。

これと一緒で一度決めた前提条件からはみ出すような概念が登場した際に、
無理にその概念を「でもその概念はこの前提スコープの中でいったらおかしいですよね」
みたいに否定してはならない。

せっかく前提の位置がおかしいかもしれないことを証明する概念要素が登場したのに、
そのチャンスを棒にふるうことになるからだ。

:::note info
さっきコンテキストマップで定めた境界の位置は、間違っている可能性がある。
それを概念モデリングで解像度を上げつつ、境界の位置の検証をしよう。

という批判的な思考を常に持っておくことが大事です。
:::



# チートポ思想を取り入れた他のチームとの連携体制
チームトポロジーを読まれた方や実践されたなら想像がつきやすいと思います。
どのコンテキスト境界内を担当されているチームと密にコラボレーション連携して、
ともにモデリングを行うべきなのか？
逆にどこのチームとは疎に独立してドメインモデリングを行っていいのか？

さらにその連携の結合度合いは、静的ではなく、動的に変化するものであるため、
継続的にモニタリングできる体制がないといけない。
このマネジメントができていないと、DDDモデリングをする効果は減ってしまう。

ここでは詳細は省きますが、Four Keysメトリクスなどを継続的にマクロからミクロ監視し、
他チームとの連携の度合いの問題点を定期的に見直す必要がある。

仮にFour Keys導入コストがないといった場合にも以下の代替案で代用ができる。

## メリット
重複概念が早期に発見しやすいため、それに伴う変更コストやテストコストなどの不確実さを大幅に減らせる。

その時その時で適切なコンテキスト境界を常に探索できる

# モデリング対象の絞り込み
モデリングコストをかけるべき対象箇所を特定するところから勝負は始まっている。


# 前提スコープを常に批判的に　
一度決めたパッケージ境界や、それよりマクロなモジュール境界などのコンテキスト境界の位置は、外部環境変化や仕様の追加や更新といった衝撃によって、容易に変更される。

変更頻度が多い箇所は、自ずと境界位置が変化しやすい部分であり、
逆に変更がほぼ入らないような箇所は、境界位置は比較的安定している傾向がある。

モデリングを行いながら常にクリティカルシンキングで前提条件(境界の範囲)を疑ってかかり、
「いま自分たちが仮定として置いていたコンテキスト境界の位置は本当にあっている？」
と検証するのです。

# 目に見えない概念をあぶりだせ
モノ系の要素やイベント系の要素は認知しやすいため、モデルに可視化できている人は多くいる。
しかしながら、私の中では業務が運用される中で常識とされてしまった
暗黙知化した前提となっているルール・制度をあぶり出すためにモデリングは威力を発揮すると感じている。


# 前提条件が変わったらさっきまでの常識は非常識

# プロセス

## マクロなコンテキストマップ
いったんマクロなコンテキストマップで前提スコープをざっくり議論し、
「どう考えてもここで区切るよね？」という現時点でのマクロなレベルの境界、
および「ここで区切るのがいいんじゃね？」というちょっと協会の位置が曖昧な部分をざっくり決める。

<img width=500 alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/312bdca5-bed0-4578-a956-4f09d0127211.png">

その中で「ここにモデリングコストをかけるのが最も費用対効果が高い」という箇所を絞り込みます。
ここの領域を俗に【コアドメイン】と呼びます。

そこにコストの8割程度を投下し、負債がたまらないようにコントロールします。

## 概念モデリングで詳細化
概念モデリングを行い、かつその中でトランザクションの単位を考え集約関係のところとかを見つけます。

この時に常に頭に思っていてほしいことがあります。

:::note warn
1つ前で仮定として置いた前提条件は、現時点での仮定に過ぎない。
間違っている可能性が大いにあるので、この概念モデリングで演繹的にその前提を検証する。というマインド
:::


:::note info
背景がそろわないところは無理に合わせようとしない。
なぜなら、そこはもしかしたら異なるコンテキスト境界内の概念である可能性があるから。
:::

## 演繹的に前提の検証


## 越境して概念の整理
越境部分はチームトポロジーのインタラクションモードの1つであるコラボ連携をする部分です。
新しい概念が発見された際に、「どのコンテキスト境界内の要素かわからない」
「マクロで見たらこの部分ぽいけど、そこより詳細なサブコンテキスト内でいったらどこかわからん」って時には、他のチームと連携してモデリングを行う必要があります。

この際に、１人以上の抽象化スキルの高い、俯瞰して考えられるファシリテータを立てることを推奨します。

## マクロなコンテキストマップ更新
リファクタリングをしたり、新しい仕様変更が起きるたびに、
都度モデリング活動をすると、前提として置いたコンテキスト境界の位置が変わったことに気づきます。

これは仕事を進めるうえで、チームの責任範囲を分けて分業したものの、
マージした際にうまくいかないから改めて責任範囲を再検討する際にも同じメカニズムです。

一度【仮定として】定義したコンテキスト境界は、変わるものというスタンスで
コンテキスト図と対応したロジックツリーを別で作成しておくことで、
上位のコンテキスト境界の位置を正しいといえるのか？の検証をしやすくすることもおすすめです。

コンテキスト図のポンチ絵
<img width=400 alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/3243c804-8ad0-4d7c-8858-a95963369a89.png">

上記のポンチ絵をツリー階層にした図
<img width=400 alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/1766e095-56d1-4cb2-9eaa-5bfa9509ad9a.png">

ポンチ絵の方の斜線で引いた境界の位置を調整するだけでいい
たとえば、受注イベントコンテキストにあると思ってたら、
実はその要素は受注ルールコンテキスト内にあるべきものであったとかいう場合なら、
大前提となるAコンテキストの境界位置まで修正する必要はありません。

## 根付いた風土を壊す
境界位置は一度定義して終わりではありません。
特にコアドメインは常に素早い変化にさらされます。
新しい概念が追加されたり、不要な概念を削除したり、、、、。
ゆえに上記で書いたように、コンテキスト境界の位置が常にメタモンのように変形し続けます。

そのたびに超高速でその領域内の価値観、文化を更新し続けなくてはいけません。


その素早さは領域の変動制に応じてグラデーションがありますが、
再利用性が求められる割と安定したコンポーネントに関しても、やはり定期的に他チームとコラボレーション連携しなくてはならない時が来ます。

その際に今の境界、枠自体がそのチームの風土を形成するし、
同時に風土がその枠の範囲を決めるという相互力学が働く傾向にあります。
これは「なんで？」ではなく、そう考えるとつじつまが合うからです。

継続的にモデリングを行い、場合によってはモデリングのプロのようなイネイブラーにファシリテートしてもらいながら境界位置は本当にこのままでいいのか？と批判的思考を持ちながらあたってみてください。

それが新しいよりベターな風土を形成します。