実践ドメイン駆動設計 第1章 DDDへの誘い

# DDDへの誘い
## DDDに期待できる事
* ビジネスドメインをより深く知る助けになる
* テストしやすくて順応性がある
* 高品質なソフトウェアモデルを注意深く作れる様になる


## 1.1 私にもできるの
### DDDの中心となる原則
* 議論、傾聴、理解、発見、事業価値が中心原則
* 上記に参加すれば **ユビキタス言語** を生み出せる
* **ドメインエキスパート** の話を聞くだけでは学ぶ力は育たない
* しかし、話しているうちにドメインエキスパートが知らなかったことが炙り出せる
* そして、業務改善を手助けできるかもしれない
* 改善するためにはソフトウェアの **ドメインモデリング** を身につける必要がある

### DDDのメリット
#### 新入りの若手開発者
* 単純な作業を、複雑なアーキテクチャになっているか理解したい
* しかし、仕事は機能追加として **アダプタ** を作成するだけ(汚い既存コードを少し修正したラッパー作成)
* 私は、もっと効率的なイテレーションを行えるやり方を知りたい

#### 中堅レベルの開発者
* まだ実力は強いとは言えないが、自分の持ち味を発揮した仕事をしたい
* しかし、根本原因をしっかりと理解できないので暫定対応だけの毎日
* 私は、熟練ソフトウェア開発者になりたい

#### ベテラン開発者、アーキテクト
* DDDに触れたことがあり、戦術的パターンの威力は一応実感している
* 会社に破壊的前進を行えるDDDを取り入れて開発に会社は興味なさそう
* 私は、ドメインエキスパートと技術者を近づけて、うまく開発したい

#### ドメインエキスパート
* 私たちの業務にITを導入しており、より良くするために開発者により業務を知ってもらいたい
* しかし、開発者は難しい専門用語に置き換えて話をするため、うまく伝わらない
* 私は、開発者と同じ土俵で話をして意思疎通を円滑に行える様にしたい

#### マネージャ
* 常に最高の結果を出したい、流行のある開発手法に幻想を抱く開発者に飽き飽き
* しかし、業務のプロたちとの密接さを開発者たちがなんとかしたがっている
* 私は、そんな業務知識を学びたがっているなら、学ばせてあげようと思う

## 1.2あなたがDDDをすべき理由
* ドメインエキスパートと、開発者を同じ土俵に載せることで、円滑な意思疎通が測れる
* 「業務側の視点を踏まえた」とは、業務担当に開発能力があったら作るソフトウェアに近づける事
* エンジニアが業務担当者が無意識に行っていた業務の知見を深める気付きを与える事もある
* 属人化をなくせる
* ドメインエキスパートと開発者、ソフトウェアの間で通訳が一切いらなくなる
* **設計 = コード** 実験的なモデルを話す事はより良いコードの設計になる
* 戦略的設計、戦術的設計の両面で健全な開発ができる
 - 戦略的: ソフトウェアの投資対象や、既存を最大限に活用する事、誰を巻き込むべきかの助けになる
 - 戦術的: 実証済みのソフトウェア構成要素を使った要素を、良いモデルとしてまとめる助けになる

### 事業価値をもたらすのは難しい
* 事業価値をもたらすソフトウェアを開発する事は、ごく当たり前の業務ソフトウェアを作ることではない
* ステイクホルダが多くいるのに価値を最大化する優先度をどうやってつければ良いのだろうか
* ドメインエキスパートと開発者の断絶は問題である。意思疎通は大事。
* より問題なのはドメインエキスパート間で相違があった場合、そもそもエキスパートでなかった場合が
* さらに問題なのは、開発の技術的アプローチを間違った方向に変えてしまうこと(既存に合わせて使いづらいなど)
* つまり、実証済みの開発手法を使う事こそ投資すべき

### DDDがどう役に立つのか
ソフトウェア開発に以下の3つを重視する手法
#### ①現実世界の事をそのまま使わず、業務により役立つモデルを一緒に作り上げる
お互いに不十分な知識を以下の作業で深い知識になり、一体のチームになる
1. ドメインエキスパートと、ソフトウェア開発者で1つのチームを作る
2. ユビキタス言語(共通言語)のを確立させる
それを用いてモデリングする

#### ②システムや事業の境界を定める
DDDそのものは事業の戦略構想に対応するため、以下のメリットがある
* ビジネスレベルのサービスが干渉するかわかる
* サービス指向アーキテクチャやビジネス駆動アーキテクチャを作れる

#### ③DDDは最高なソフトウェアを作る助けになる
戦術的設計ツール群を使うと
* テストがしやすくて、エラーが発生しにくい
* スケーラブルで、分散コンピューティングにも耐えれらる


### ドメインの複雑性にどう立ち向かう
DDDは複雑なソリューションを単純化する
#### コアドメイン
もっとも複雑で、価値があり、見返りが大きいところ
#### サブドメイン
* コアドメインの次に優先度が高いところ

#### 複雑とは
1. メソッド数が30を超えていないか
1. 将来アプリケーションが複雑になる可能性があるか
 - ドメインエキスパートがより複雑なシナリオがありえるか考える
 - CRUDのアプローチのみで解決でききないか
1. 何年にもわたって機能変更が続いており、いつ変更が落ち着くかわからない
1. 初めて使う人がすぐに理解できるかどうか
 - ドメインエキスパートと享禄して実験的なモデルを作成して正しいか確かめる
1. ドメインモデルと読んでいるものは、getter, setterが大量に存在するだけのものかどうか


## 1.3 DDDを使う方法
### ユビキタス言語
* ドメインエキスパートを含む、チーム全員で共有する言語のこと
* 開発者とドメインエキスパートを同じ土俵の上に乗せるだけではない
* 作って終わりではなく、育て続けるもの

### ナースが注射を行うとき
* UMLなど形式的なことは

#### ユビキタスではなるが、ユニバーサルではない
ユビキタスは、チームによって話されて、チーム開発する単一のドメインモデル
世界中共通言語ではない




## 1.4
### 組織としてドメインに関する有用なモデルを獲得できる
* DDDはビジネス的に重要なところ(コアドメイン)に注力する
* その他のサブドメインがコアドメインを支えてたとしても注力する
* なぜなら、自分たちの領域に注目すれば、周りに領域、競合との差理解されやすくなる。

### 事業についてより洗練された正確な定義ができてさらに深く理解できる
* コアドメインについてのユビキタス言語を考えると、ビジネスに対する理解が深まる
* これは、ビジネスの現在の価値や今後の方向せいを分析できる

### ドメインエキスパートが、ソフトウェアの設計に貢献できる
* ドメインエキスパートが違うバックボーンできたため、意見が違うことや属人化してる事がある
* しかし、DDDを進めるとドメインエキスパート間と、技術者で合意形成(ユビキタス言語をOUTPUTとして)できる
* 結果、組織内で全ての人が使えるようになる

### より良いユーザ体験を提供できる
* 業務をソフトウェアに落とした
* しかし、業務のエキスパートのためにソフトウェアを作ると、他の人は使い方や、その結果が不正確な元となってしまう
* ベースとなるモデルにしたがって設計されたソフトウェアなら、ユーザの教育を減らし、生産性をあげれる

### モデルとモデルの間に明確な境界を定められる
* 技術者はビジネスのために仕事をして、技術そのものに楽しさを見出せなくなってしまっている
* 方向をしっかりと定めれば、ソリューションの有効そいに注目でき、有効な作業ができるようになる

### エンタープライズアーキテクチャが、より整理されたものとなる
* ドメインがしっかりと定まっていれば、どこで統合が必要になるのか理解して開発を進められる
* お互いに関係するモデルをもつチームはコンテキストマップを作成することで、よりよく理解できる

### 戦略的な面でも戦術的な面でも、新しいツールを使える
* 境界づけられたコンテキストを理解していれば、モデリングの境界もはっきりする
* しかし、境界が被った場合一つのコンテキストに異なるチームが関わる事がある。
* その場合戦略的に切り分けて、統合を、モデリングツール(集約、エンティティ、値オブジェクト、サービス、ドメインイベント)をしようする

## 1.5 導入の課題
3つの課題
* ユビキタス言語作成の時間確保する
* ドメインエキスパートを常に参加させる
* 知識をソフトウェアに落とすのだから必要
* 開発者たちに、考え方を返させる
### 実践的な指標
* コアドメイン: 領域は長年変化し続けることはない
* 汎用サブドメイン: 実質的なコアドメイン (?????)
* 支援サブドメイン: コアドメインになることはない、支援機能。長年生き続けそうなら、戦術的設計を行う

### ドメインモデルを作る指標
* ドメインエキスパートをチームに参加させられるか
* 機能が、今後複雑化するか
* 他のコンテキストとの統合を簡単に行えるか
* トランザクションスクリプトを使ってシンプルになるか
* 戦術的パターンを採用して、納期に影響がないか
* コアドメインに戦術的な投資すれば、

### DDDは面倒なものでは無い
1. ドメインオブジェクトがクライアントからどう使われるべきかテストをかく
1. テストを通る最低コードを記述し、ドメインオブジェクトを作成
1. メインオブジェクトのメソッドシグネチャを決める
1. メインオブジェクトを実装し、重複が残らないようにリファクタリング
1. チームにテストコードが、ユビキタス言語にしたがっているか確認


## 1.6現実味のあるフィクション
自分たちのDDDが泥沼にはまらないために第三者視点で

### SaaS Ovationとそのプロダクト群、どう使ったか
* 最初は企業向けのSNSを開発。次に作ろうと決まったのがスクラムプロジェクト管理
* 全く別のプロダクトだが、まとめて一つのプロダクトとした
* しかし、ユビキタス言語を育てない軽量DDDを行ってしまった。
* 結果、二つのサービスをきちんと分離することができず、競合してしまった。

この先の話は第2,3章で語る

## 1.7　まとめ
* DDDをどう活かせるか、ドメインの複雑性について
* 採用するに値するかの診断
* DDDと取り入れないと起こる問題
* 概要
* ステイクホルダーへどう売り込むべきか
* 問題に直面した時にどう進めれば良いかの解説







### キーワード
* ドメインエキスパート: 業務の流れをよくわかっている人
* ユビキタス言語: そのチーム内で共通認識を持てる言語
* ドメインモデル: 業務ドメインに特化したソフトウェアモデル。扱うデータや振る舞いを業務的に正確な意味合いで保持する