DDDをチームに導入する際に考慮した4つのこと

この記事はドメイン駆動設計 [#1 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/ddd) 20日目の記事です。

チーム内導入 = DDDでシステムを組み上げたよーではなくて
チームでDDDを使ってシステム開発しようという合意をスムーズにとるために考えたことを共有します


# 状況説明
状況がわからないと想像しづらいと思うので、まずは簡単な状況説明を...

## 私個人について
- プログラマ歴5年
- golang suki!
- 前チームでDDDに則ったシステム開発経験済み
- 個人的には設計周りの経験は浅い
  - チームの強い人が設計してたので、個人的には軽量DDDレベルで開発してた
  - 軽量DDDにも満たないかも...
- 複数の副業先で前チームの知識+副業先の強い人の意見をもらいながら軽量DDDで開発を行い、ディレクトリ構成をupdateし続けていた

## あらまし
* 全社的にレガシー脱出しようという機運
* その流れでプロダクトを5つ保守するチームが爆誕し、そのチームに引き込まれる...
* 5つともレガシーで伸びしろ(良い言い方)がすごい
* 5つのうち2つに関してはそのまま引き継ぐのではなくリプレイスを行うことになってた
  * 開発陣は3つのプロダクトの保守や改善(これをしないと開発速度が爆遅)を行いながら、2つのプロダクトのリプレイスを行うことに...ナニイッテイルカワカンナイ
* 唯一救われることとしては締切がほぼほぼないこと

## チームメンバー構成
スクラムで開発を回しているのでその役職と詳細を記載します

PO 1名/SM 1名 /DEV 4名　の計6名のチームです


ざっくりスキルを図で表してみました
![skill.png](https://qiita-image-store.s3.amazonaws.com/0/59905/d9d11c0f-6b02-326b-081b-9a5229f5179f.png)

チームのスキルグラフから見て分かる通り、リプレイスにおいて必須スキルな設計がとてつもなく弱いチームなことがわかります...
上記状態だったので自分が経験したことのあるDDDで推し進めることにしました




# 4つのDDD導入へのアプローチ
## 1. DDDについての説明とどう関わってくるかを意識させる
そもそも自分の知識が薄かったので、[わかる！ドメイン駆動設計 ～もちこちゃんの大冒険～](https://booth.pm/ja/items/392260)を購入
ある日の午前中に3章まで読んで、自分の中でまとめて午後にメンバーに向けて内容の共有会+リプレイス時にこの手法を取り入れたいと思っていることの頭出しを行いました

所要時間: 2時間程度
共有した内容:

* ドメインとは?
  * 事業の対象領域
  * 旧システムだとドメインはここにあたるよってことと、ドメインの再定義を行う必要があるよね?っていう話をした
* ユビキタス言語とは?
  * 概念に対して同じ言葉をつかって話していこう、リプレイス時のソースコードでも変数名などでそれをそのまま使うよって話
  * まずは旧システムを保守している人をドメインエキスパートとして参加してもらいたいこと
  * その際の関係性として前みたいなDEV - 通訳 - ドメインエキスパートみたいな関係ではなくDEVとドメインエキスパートが直接やり取りできるような関係にしておきたいこと
  * 引き継ぎ時にユースケースをドメインエキスパートと出しながら、ユビキタス言語を洗い出しておきたいと思っていることを共有
* ドメインモデルとは?
  * ドメインを構成する物・概念・振る舞い・関係性
  * 最終的にはそれらをコードでのみ表す
  * 運用に乗った場合はドメインモデルに対しての変更をイテレーティブに行っていく


伝わって欲しかったこと:

- DDD試してみないか?
- ドメインエキスパートの協力を得たい
- 現状のユースケースとユビキタス言語を出そう
- DDD難しいから学習時間抑えれるようにして皆で学習していきたい

## 2. 学習時間の確保
POに現状のチーム全体のスキルセットを再共有し、リプレイスする上で必要な設計の知識が今のチームにはないことを認識してもらう。また、設計に力を入れる理由を説明し学習時間の確保をお願いした

以下が学習時間確保のために話した内容

* DDDは最初は時間がかかりそう
  * 学習と設計、進め方の整備
* プロダクトが長く息をしそう(使われるのがわかっている)なので変更容易性が高い、かつ設計をコードで保守できるDDDがよさそう
* チームに対してのプロダクト数が多いので保守性を高めて後々かかる人件費を抑えたほうが良い
* 私が頑張って主導します
  * ここで テンプレートは個人的に用意してあって、それ使うから実装時間短縮できますとかもカードとして切った
  * https://github.com/mafuyuk/ddd-go-api-template 内容はちょびちょび変わるかも


これによって、DDD学習時間を工数として手に入れました
このタイミングでDEV陣にはDDD本を全員購入してもらった(会社の金で!)

## 3. 学習体制を整える
まず学習体制を組みにあたって考えたことは誰がどこまで、いつまでに理解できたらいいのかを考えました

以下表はその際に出したものです。スクラムのRole+ドメインエキスパート各々がDDDの把握しておくべき概念とそれによって何をできるようになって欲しいかを明示し、その内容を各Roleに共有し合意を得るようにしています

| Role | DDDの把握しておくべき概念 | 概念を把握することでどういう行動を望むのか |備考|
|:-----------:|:------------:|:------------:|:------------:|
| PO | ユビキタス言語、コンテキストマップ | ドメインを定義できる。ドメインに対しての追加修正の可否を判断できる |DDD本の1~3章|
| SM | ユビキタス言語、コンテキストマップ、ドメイン、エンティティ、値オブジェクト | ドメイン領域にどんな値オブジェクトが定義されているか？オブジェクト同士の関係はどうなっているか？を概要レベルで説明出来る |DDD本の1~3、5章|
| DEV | 全部 | DDDに沿った開発、運用を行える。メンバーの教育が行える ||
| ドメインエキスパート | ユビキタス言語、ユースケース | 引き継ぎ時の要素の洗い出しを行える。要件定義をDEVと同じ言語を用いて共同で進めることができる |DEVが引き継ぎ時に共有する|


学習スケジュールとしては4週間でエリック本を読破してその内容をチーム内共有することにしました
チーム内共有資料を用意して共有を行うのはDEV陣でPOやSM、ドメインエキスパート(希望者のみ)は上記で明記した内容が共有される会に参加(把握しておいて欲しい会への参加をDEV陣から促す形)して知識向上するという形で進めてます

共有内容はこんな感じ → [DDD本3章を読んでこのように理解しました](https://qiita.com/mafuyuk/items/18040296b57687422ec5)

学習体制に関しては、保守や改善、リプレイス側でも思わぬものが出てきたりでスケジュールは崩れつつあって都度見直しをかける予定です

## 4. ドメインエキスパートからの旧システムの引き継ぎと関わり方の相談
旧システムを保守している方、仕様に詳しい方をドメインエキスパートとして参加していただけるようにお願いしています
その際に説明したことは以下です

* リプレイスに至った経緯
* 現状のリプレイスの体制
  * メンバーやスケジュールなど
* DDDについての説明
  * メンバーに頭出しするさいにつかったまとめの共有をここでも行っています
* ドメインエキスパートというポジション
  * 上記に記載した`概念を把握することでどういう行動を望むのか`を共有し、お願いするようにしています。
  * どこまでやれるようになって欲しいかを明確にしていることによって負担がすくないことを事前に共有ができるため好意的に捉えてもらえています


その後、DEVメンバーと一緒に現状使われている仕様のユースケースとユビキタス言語の洗い出しを行うようにしました

# まとめ
現状までの簡単なKPTをメンバーにしてみた結果を 好感触だったこと/うまくいかないこと(うまくいくようにしたいこと) とまとめてみました
うまくいかないこと(うまくいくようにしたいこと)で出たことは来年の課題ですね:muscle:

## 好感触だったこと
- RoleごとにどこまでDDDについてどこまで学習すればよいか明記する
- チーム全体でDDDについて学習をやっていこうという姿勢
- 主導する人がいる(私)
- ドメインエキスパート-DEV間に通訳をなくして直接ユビキタス言語を使って話すこと
- ドメインエキスパートという概念があるので、今までみたいに要求側と開発が分断されづらい
- 設計をコードで表すことで設計が失われないこと
- ドメインを理解して設計することで、ソフトウェアの本質を捉えた良いものが作れそう
- ユビキタス言語によりコミュニケーションが取りやすくなりそう

## うまくいかないこと(うまくいくようにしたいこと)
- ドメインの抽出
  - まだ引き継ぎ途中なので仕方ないのかもしれないのですが、リプレイス時にドメインの再定義をこうやるといいよ～など情報があったら共有いただきたいです:bow:
- リソース不足の状態での工数捻出
  - 工数は捻出しているけど結局割り込みの作業などが発生していて予定通り進めれていない
- DDDがそもそも難しい
  - 講師が欲しいなー(チラ
- DDD以外の設計手法を選定していない
  - 手続き型は例外として他の設計手法を吟味できていない感が強いのでDDD以外にこれがいいよっていうのがあれば教えていただきたいです:bow:
- ドメインをコードで表すことになるので、技術に弱い人がどこまでDDDの思想について来れるかが不安
  - コードがわからなくて「ここの仕様資料にまとめて欲しい」とかでてきたら困るけどそれをどう回避するのか...悩ましい
  - チームによってはここで妥協が必要になったりしそうだと思っている
- ユビキタス言語の洗い出しが今回のプロダクトだと関連事業部が多くて意外と時間かかる(けどドメインを明確にするためにやる必要がある）
- エリック本の前半が抽象的なので、具体例があるとわかりやすい
- 設計を経験したことがない人にとっては、何がメリットになるのか分かりづらい
- 初学者に対して理解しやすいドキュメント（資料、書籍など）の選定が必要
  - 良さそうな資料↓ あとは講師の方をお招きするとかもありかなーと思っている
  - [わかる！ドメイン駆動設計 ～もちこちゃんの大冒険～](https://booth.pm/ja/items/392260)
  - [ボトムアップドメイン駆動設計1](https://www.slideshare.net/MasanobuNaruse/bottomup-ddd-1)
  - [ボトムアップドメイン駆動設計2](https://www.slideshare.net/MasanobuNaruse/bottomup-ddd-2)

## さいごに
こんな感じでうちはやっていますという共有でした
DDDを導入するのはメンバーが揃っていないチームには結構重いことだと思っているので、こういう試みをしてやっと入れれた感(導入途中だけど)がありました

現状は`4. ドメインエキスパートからの旧システムの引き継ぎと関わり方の相談`の途中なので、このやり方+αでうまくできたーやうまく行かなかったーがあったら加筆修正または新しく記事投稿してみようかなーと思います

まだ要件定義までいっていないので引き継いでドメインを設計する際にそもそもこのシステム必要なの？とかスコープ小さくしようなどの議論が発生すると思っていて、DDDは使わず行く可能性はまだまだありますが個人的には設計周りは結構楽しいなーと思っているのでその界隈の人たちと繋がって情報交換などしたいですねー

よかったら情報交換させてください:bow: 
Twitter: [#mafuyuk](https://twitter.com/mfykmn)