ユースケースから始めるドメイン駆動設計

### ユースケースから始めるドメイン駆動設計の手法を紹介
台風で予定がなくなったので久しぶりにがっつり書きました。

#### 概要
最近、DDDによる開発が盛んですね。
DDDはひたすらドメインを分析してモデリングしていくための手法ですが、ユースケース駆動開発とはとても相性が良いと感じています。
そこでユースケース駆動開発から始めるドメイン駆動設計の手法を紹介したいと思います。
ドメインレベルにクラスを落とし込むことまでを目的としています。
ユースケースから実装までの流れがつかめればと思います。

#### 0. 機能要件
どんなシステムを開発するにしても要求というものは存在します。
「顧客が抱えている問題は何か」を理解し「システムが何を提供できるか」を定義するフェーズになります。

例として「食生活の管理がしたい。」をもとに設計してみたいと思います。
#####機能要求
- 毎食の食事のメニューを登録できる。
- 食材を登録することができる。
- 毎食の食事をメニューから選択して登録することができる。
- 過去に食べた食事の内容を確認することができる。


#### 1. ドメインモデリング
最初のドメインモデリングではモデル候補を洗い出すことを目指します。
ここで洗い出したモデル候補をドメインモデルへと育てていくことになるのですが、最初の段階で完璧に洗い出すことはできないのであまり時間をかけ過ぎるのは得策ではありません。
以降のユースケースモデリングやロバストネスモデリングではここで洗い出したモデルを修正したり加えたリしながら育てていくことになるので最初にすべて洗い出せなくても気にすることはありません。
モデルの見つけ方は顧客とのヒアリングで出てきた単語がキーになります。
顧客との会話の中で出てきた単語のうちの名詞がモデル候補で動詞は振る舞い候補となります。

![alt](http://www.plantuml.com/plantuml/png/SoWkIImgAStDuNgslk_bulaAUderTWf0nfDTtLmGIY5VLrVXSVF2nytTZvkNFcxUmuNC0Sc2r3-REu4BGa7KDwr-tBpsSVCga7g7rBmKe1K0)

#### 2. ユースケースモデリング
次にユースケースモデリングを行います
ユースケース記述は以下の事に注意して書く。
**ユースケース分析の結果をレビューしドメインモデルを適宜更新する。**

- 主語、述語、目的語で簡潔に書く。
- ユーザーとシステムの両側を書く。

##### ユースケース図
![alt](http://www.plantuml.com/plantuml/png/SoWkIImgAStDuNhSlEnnyvx7JTk0f8AkdOB6oyNpdysTyBXfqlEPkr_sR7hSEFDnKxScLdLFTdK_Rbptk7dXu-RknyrBWJ94QoEihh7lQT_knushWHeUD-vyt3WVRk7JjjQdwtQ2Z5YqwyMgNfWH3gbvAK0V0G00)

##### ユースケース記述
| -|  食材を登録することができる|
|:-----------------|:------------------|
| 基本1|ユーザーは食材登録画面にアクセスする。|
| 基本2|システムは食材登録画面を表示する |
| 基本3|ユーザーは食材名とカロリーを入力して登録ボタンをクリックする。|
| 基本4|システムは入力内容をチェックしてデータストアに登録する。(代替1)|
| 基本5|システムは登録完了画面を表示する。|
| 代替1|システムは入力内容に不備があることを食材登録画面へ表示する。|

| -|  毎食の食事のメニューを登録できる|
|:-----------------|:------------------|
| 基本1|ユーザーはメニュー登録画面にアクセスする。|
| 基本2|システムはメニュー登録画面を表示する |
| 基本3|ユーザーは食材を選択し、メニュー名を入力して登録ボタンをクリックする。|
| 基本4|システムは入力内容をチェックしてデータストアに登録する。(代替1)|
| 基本5|システムは登録完了画面を表示する。|
| 代替1|システムは入力内容に不備があることをメニュー登録画面へ表示する。|

| -|  毎食の食事をメニューから選択して登録することができる|
|:-----------------|:------------------|
| 基本1|ユーザーは食事登録画面にアクセスする。|
| 基本2|システムは食事登録画面を表示する |
| 基本3|ユーザーはメニューと日時、ラベルを入力して登録ボタンをクリックする。|
| 基本4|システムは入力内容をチェックしてデータストアに登録する。(代替1)|
| 基本5|システムは登録完了画面を表示する。|
| 代替1|システムは入力内容に不備があることを食事登録画面へ表示する。|

| -| 過去に食べた食事の内容を確認することができる|
|:-----------------|:------------------|
| 基本1|ユーザーは食事確認画面にアクセスする。|
| 基本2|システムは食事登録画面を表示する |
| 基本3|ユーザーは日付を選択して確認ボタンをクリックする。|
| 基本4|システムは入力内容を確認してデータストアからデータを日時昇順で取得する。(代替1)|
| 基本5|システムは食事確認画面へ結果を表示する。|
| 代替1|システムは入力内容に不備があることを食事確認画面へ表示する。|

#### 3. ロバストネス分析
ロバストネス図はユースケース記述とドメインモデルを元に記述する。
ユースケース記述の名詞はエンティティ候補であり動詞は振る舞い候補になる。
また、ロバストネス図上のエンティティはドメインモデルと過不足無く一致していなければならない。
**ロバストネス分析の結果をレビューしユースケース記述とドメインモデルを適宜更新する。**


##### ロバストネス図

![alt](http://www.plantuml.com/plantuml/png/ZLFDIW9X5DtVfxWle60_1RC8Tos2Ue4sayuYi1aOnqNBx_lGHIc81I4caPP9aK91f1FuCDTFyoqQPyRwI1tT29uvvzvppfr9PXtTTd9d6SXbZPIUDN3Il1lLoyGhuwexARuHgnA_1D1JZcKZYHQ9B-8VtY-SM3aphTldeIJWZw_TIRq102dBT6mhWz_txV53Fnmp0sN-KLxKP24lEprl5Gb6_8c48Dxznnn-bYIl4YiIunvEx8fOsvC4OtzfmNBPAGxxXS327mSCqpbrPZPLYP9FJOQnsDw2K1eca7XZwf6xn7imJ_6LQc8DDq3zZ_7uuj6RwpdO2b5PBlazl91u9V7i2ol7Pj0hiHjYhJ2Vk2K-8F4-hPbtFMvGynBpgo-ZuJQi9FcZea-duGuUxaCqQMbTGxSvgWqIQpfHJptTUtG0AgIqFOz7l5ceuIv4FL_i7Y1fc6dlc_i1)

![alt](http://www.plantuml.com/plantuml/png/ZLFBQi905DtVhvWVKB2F5h8GTrqKsXzmaseM1Pj0Z8ikPmPT-01f2qMiBMgrqeL22qLDmO-vHfk_wCG1EpPet0HoppdtdZDt9fLtTDiftEIWa3SoUjuWoDl8AyXxoB-HtIqRhb_zGDf0LW7GCuvb2qf_1Nw9BrnP1JEhsxSRGgbQFhX-gmC06SjqR2j7Vjg3vUjKDbiNlMBFApUzKj4RJiH0v1JP6tAERFIFEH_NFDP0MaNAH1tfFTA1aCYsQveSxWshysb9MlZZW64wrywcMLMeP5LJabWiIVpkow9LLwDf946GTGAdp4KsWJ1bfLHpQ-G0r7yIZoUtdfr63iC-jfEFY4f6Ef9-H7oVZXVbPwIFQLELU_MQ0EK618YqdpPbI-HFo6R8FmKUvEFlSYMWoaD18tUfaME890Mj8fQjaHDoSGQxIH57EtUxY-OiiQSVzN84qo_FGIs5DXD6TznBef5J2EFx9G586MPMlE5V)

![alt](http://www.plantuml.com/plantuml/png/ZLDFQ-905B-_Jp5VGC7zimivYBSzBEn-0IzPpM71JI36mnvd1eMgXT8M95XRr6fj2mej53K5FynBOlCjcZZMZeqrlGJovlVU-_sPoPKjrRGg_qfGAMi5jQoHe7_XpXl8Zf5taJUG3v0_8Wqh1m6T-lLpf2samwNj1Cqxf3Qo1e1Qi0oJ81z6MFOGVk6FKT6Bglb_FL3WbwTEqEa1GC7GBTCeaQVkQ7av5sCsHQywyEfjhrRrnhCL4Ohi2Zb7Ddc3TAU77hEHDf6oi8xq1EaeR15ZDp2nt1ittNbDK7Z5WAPRVwqNcbABh4zMHbAfR8JsEqUoA8La2B9Un94vo6OGXwmwPSKA-GJoFqcdiplyKiZddGnYi2zR4I2TR6Suybi3tsPv7VarSXlvRMY3C5k4cjVNilaPiWNo-_0y4iHlXFiWbiOq9GQcaA-G28f69IIga6_arm_O3thNHTVf--r5veDCv1iGxVtz4-II54AylkV24OLyX_Xv4dk0dAONmuVw3000)

![alt](http://www.plantuml.com/plantuml/png/ZPFDJi9058Ntzodk2q22_tPXsBamqHTmKw4B4soJKXOkPoPe0X8JDIB1dmY2X0KiJ0nG8mzpMtxUmga50ag1JPFEd7FxdNlIQD9IJIjrbe1KKekfIGs7vHUdaoNMS2_IRgDD_APVwWpgEM85uba0DMOP9fAealWY_YcVS6AazBXgde-ylhv_Pm-VIW0GCtJBD18uUAtrtpgZCUD3DrrnCyN9fqWmukya1F7c7wNJohcyGEoA69Vdn6w9rQJ57mkWwTQfDKQOk4XS_d9sfTAzldU_y-CSqmam5DgR0wzW18cNF1Pk4s_3Vuddd4ccu1fClsCuF7_q-ce46pEh9jRivIkE_I3Z35chbtac9XDLZtNVHUBHooe-vBs7BUh-BWF8bwzVmKrOAl96BUb7mIqyt8V5ei1TENQvL-n6LYG9wjnZE3g0eEkf2XJSNYoRQLZ1dTKgtmM8QdfS_cq_)


#### 4. シーケンス図
さて、ロバストネス図までおわりました。
次はシーケンス図を描きます。
シーケンス図が描ければクラス図の関係がわかり詳細設計が出来たも同然となります。
シーケンス図はドメインモデルのモデルとロバストネス図のコントローラーを使って描いていきます。

ここまでは順調にできました。
早速はじめてみたいのですがシーケンス図を描き始めて何かがおかしいことに気が付くはずです。
そう、このままだとシーケンス図が描けないのです。

試しにシーケンス図を描いてみます。

![alt](http://www.plantuml.com/plantuml/png/hLFDIZfH5D_FKvmNy0LS_77tNmJr0cwcd8LW8-WrQ7dFHHUb81A4b8HM9aaA1Q5EqCFyl9blqNWlJXA3ZT1cE7Fl-NsSZvif2xSaAiS5npqInH91zQ7UmA_XrpaiLloSMpgbvUtDHwUvQ0VB-lFY8bXsUexdYxnOtpZE9evIgNyn44eJk0SUWmFmT2MOFt655yTEH74CySHf-kmE5dSpo3RuV1jsqsMQDg_1BKlYvBnjnX8MQWzrim4v00-Xdg0U3QwLzNNrNfzTGLv2zYqEwXhy3lMIzSCCyDXagp2mDVrbhwowhbNrQBeIKnByOCKCrMzI9gSWQFz_z9kmup-qvN0-QMXkGzOXEQmIgcjy10OnYKOIwNY5iaS7UqbqxV5wnhQBtpn-BefDi7NckowK7jNdizfkQvK9BOMFy0i0)

おーー！なんか描けました。

いたって普通のシーケンス図が描けました。
「めでたしめでたし」ではないですよね＾＾；
やりたいことはDDDでしたね。

何がイケてなかったのだろうか。
シーケンス図はロバストネス図を元に描いていくのできっとロバストネス図が悪かったはずです。
というわけでロバストネス図を描き直してみます。

#####修正したロバストネス図
![alt](http://www.plantuml.com/plantuml/png/ZLNFxj904BxlK-mBGEB1YmU32O_XfK8F9jWcRJbut5r1Wn296Wb18g8YaGX1ZF87vM66fVOjdBQ0GhVRtwLfPhvllftPRzg2wncELtrK8LNNB1ckIOCFxmxzDl2NVdSJDBy1wm9_JeXHyco7WXY1s0B_WK_omAvQPSDvVAJ4UF_r9kWF2I6cvJtqJZdWGn0T45-0pwC2Fq5y1h4W9Tlo7BkYA84d-FD-x7zSNs72-EwNR0oeuTAqklUAnIGDnDC8imE-0l4ivB99B4dEwFso9NaNM1COnyQ1lG8sJfubfibfSx-kNvttglMWL_U_Fm4nGMrKrNIZ9YHREOYQ7CoHAL-yaRyxbt9dhAnzaesUhDVaT1Krpu3ZQ0JmsIKZd9xe0r-Y6BwV2wZ6jJoDwtyZq5pkhk82xz1R54ce1to3DKWIWimiW-ZJM41hdMnsndthqpIVLtMUBQlrZpAd5qo4iYatlCFRnwXijwBEqPLV8yTixrke4RiCM0VOA2Q2U1jwHYoYFF0PecFRPOz5ky-QN4XLcraPHRZMtTbAYhrMHaDuwbgdKzHxhep-WvCqdGG40zhF0o45qohZJ-4l)

上記はアプリケーション（ユースケース）と集約ルートとドメインモデルとリポジトリを使って作り変えたものです。
それでは上記のロバストネス図を元にもう一度シーケンス図を描いてみます。

#####シーケンス図
![alt](http://www.plantuml.com/plantuml/png/hLPFJrD14B_lfzXZUsYyzs2uzK1IlW2NXRv3a_eWvQ7n-7OK3T9020aXsAXLeVwFGhHI3HzcUDH-2sVRDJoMsRN9euTcsPdv_UOtVvREhIMgdQpVQmcrdAoq9S8HmY_Kt-bRBAsinmtLVYZ7hrzSTdT61yFnrhVHtd3SxObL2cikDrTLd5WpwXx2Fi9xr5yd63yGZX5E6DVnuSRez1721-C7JnaF3f-GeOjwG15q5WsLg2Mr5ac49nE-SzG_ZKttH5w6h5JkCWggqYIilw0UKfoHtxolaeZJAgLahYKFozoXthtStgQp5ucWyYbxGFwywe_Ud8b654hMqHxACTlfODfVZ55J8pwP-fgutUpnsspp4DDzJ8yMusaWmdDJO3WXkocQyGKw5AYRVsAgCeuU_CUdL2u0R-rKqVFVsUPBY-L8ySwpj9-m6-N1JxjLnvbAvUBWl3PN7xE4ClTXFQv8yn8iWOV4sbnaMSbXsNc35FNnlwbg9R9USuDv07-RKVSHtfaxKuszh7Dw3V767Wcl9LIhMJl6hw9LVp7ePFhWQiVz1C67GqGjUX0Nvg_5ppvJ_4jhkysPIkNYu5Nc0STqCDN9Z2-FarVCUr0A35EG7LDgoJDslfamjscCYwpuwu3mSUBNfNBHeRGmVwTUA_icDapFSyoqD4uQ_4w46a2xwuBOYIowAjE_iizR5sSRqxkR2pDP09U-Nhiz-loZudB73S6NoaCbPbthyBzympj7N_GpxYy0)

それっぽいシーケンス図になりました。
作成されたシーケンス図はユースケース記述と合致しているか（要件を満たしているか）を確認し、ロバストネス図とドメインモデルとも合致しているかレビューをします。

#### 5. クラス図
シーケンス図とロバストネス図からドメインモデルを更新してクラス図を作成してみます。

![alt](http://www.plantuml.com/plantuml/png/SoWkIImgAStDuKhEIImkLdYvUFwpkHCUDorwt3pzSVEgnqqR7pVlUToq_N7pyiVDcnMgkHI0G1UgxENijkTRMXuthmQfQUwmmYwCeWLaPlFSnqqxW190jXLsOR0MRGAEqT14KpRfnVwzJxiM0CLh4Rx1T0-Q9s1EG1Y6gGNJggVzqvxkc_wuSURZfcuDJIk8E9gzS8kUJkXzsjaBvJnk0Xgw5kpXFIYcQa2KwQ2eW5aCaODR3BHIeRYaA3Cl7IAFeWT5LMPU2SnPsCCQwafjxB9mdpzkRWSRlVznqqwW52XI6dSydxdxPSyc3MX0GYXGw7CHI4Rvkhfss4EQQ9sOQGQhUSWQkB3x7qc1GsfU2Z0l0000)

大変な駆け足でつくったので見苦しい点はあるかと思いますが１つめのユースケースだけは何とか完成しました。
ちゃんと見直したら修正したい箇所は沢山出てくると思いますが、DDDに落とし込むまでの流れがざっくり掴めれば十分だと思います。