狠狠撸

狠狠撸Share a Scribd company logo
2020.3.8
松岡 幸一郎 (@little_hand_s)
1
ドメイン駆動設計
モデリング/実装入門 勉强会
自己紹介
● 松岡 幸一郎 (@little_hand_s)
● DDD community jp主催
● DDD周りの話をするブログ書いてます
● WEB+DB PRESS 2019年10月号 特集「体験ドメイン駆動設計」執筆
2
本日の趣旨
3
● 「ドメイン駆動設計 モデリング/実装ガイド」
技術書典8向けに執筆
● 発売記念として、本書の一部内容+αを
オンライン講義形式で解説します
● オンラインで既存のオフライン勉强会をどの程度代替できるか、
の検証としての試み
オンライン勉强会というチャレンジ
オフライン勉强会
● 前に立って発表
● Twitterのハッシュタグツイート
● Sli.doによる質疑応答
● 登壇後の個別質問
4
オンライン勉强会
●
●
●
●
● オンラインで既存のオフライン勉强会をどの程度代替できるか、
の検証としての試み
オンライン勉强会というチャレンジ
オフライン勉强会
● 前に立って発表
● Twitterのハッシュタグツイート
● Sli.doによる質疑応答
● 登壇後の個別質問
5
オンライン勉强会
● YouTube Liveによる配信
●
●
●
● オンラインで既存のオフライン勉强会をどの程度代替できるか、
の検証としての試み
オンライン勉强会というチャレンジ
オフライン勉强会
● 前に立って発表
● Twitterのハッシュタグツイート
● Sli.doによる質疑応答
● 登壇後の個別質問
6
オンライン勉强会
● YouTube Liveによる配信
● Twitterのハッシュタグツイート
● Sli.doによる質疑応答
●
● オンラインで既存のオフライン勉强会をどの程度代替できるか、
の検証としての試み
オンライン勉强会というチャレンジ
オフライン勉强会
● 前に立って発表
● Twitterのハッシュタグツイート
● Sli.doによる質疑応答
● 登壇後の個別質問
7
オンライン勉强会
● YouTube Liveによる配信
● Twitterのハッシュタグツイート
● Sli.doによる質疑応答
● YouTube Liveのチャットによる質問
やりとり
質問受け付けます
● sli.doで質問受け付けます
○ https://app.sli.do/event/imvxc56h にアクセス
○ 質問を追加 or 既存の質問に投票
8
質問受け付けます
● sli.doで質問受け付けます
○ https://app.sli.do/event/imvxc56h にアクセス
○ 質問を追加 or 既存の質問に投票
● ツイートは通常のイベントのようにお願いします
○ Twitterハッシュタグは #ddd_guide
○ YouTube Live上のコメントもOK
9
不慣れな点も多々ありますが、お付き合いお願いいたします
10
スポンサーご紹介
11
GOLD?
スポンサー
予算策定のGitHub を開発?
実績/調達? 技術スタック?
シンガポールの?
VCから調達?
ログラスDDD勉强会を開催しました!|坂本龍太: Loglass|note ?
今日話す内容
15
● DDD概要
○ DDDとは
○ モデルとは
○ 良いモデル、良くないモデル
話す内容
16
● DDD概要
○ DDDとは
○ モデルとは
○ 良いモデル、良くないモデル
● モデリングから実装まで
○ ドメインモデリングの方法
○ ドメインモデルを実装に落とす
○ ライブコーディング
話す内容
17
● DDD概要
○ DDDとは
○ モデルとは
○ 良いモデル、良くないモデル
● モデリングから実装まで
○ ドメインモデリングの方法
○ ドメインモデルを実装に落とす
○ ライブコーディング
● プロジェクトへの導入方法のススメ
話す内容
18
● DDD概要
○ DDDとは
○ モデルとは
○ 良いモデル、良くないモデル
● モデリングから実装まで
○ ドメインモデリングの方法
○ ドメインモデルを実装に落とす
○ ライブコーディング
● プロジェクトへの導入方法のススメ
● 「ドメイン駆動設計 モデリング/実装ガイド」他の章の紹介
話す内容
19
● DDD概要
○ DDDとは
○ モデルとは
○ 良いモデル、良くないモデル
● モデリングから実装まで
○ ドメインモデリングの方法
○ ドメインモデルを実装に落とす
○ ライブコーディング
● プロジェクトへの導入方法のススメ
● 「ドメイン駆動設計 モデリング/実装ガイド」他の章の紹介
話す内容
20
1章より
● DDD概要
○ DDDとは
○ モデルとは
○ 良いモデル、良くないモデル
● モデリングから実装まで
○ ドメインモデリングの方法
○ ドメインモデルを実装に落とす
○ ライブコーディング
● プロジェクトへの導入方法のススメ
● 「ドメイン駆動設計 モデリング/実装ガイド」他の章の紹介
話す内容
21
1章より
2章より
● DDD概要
○ DDDとは
○ モデルとは
○ 良いモデル、良くないモデル
● モデリングから実装まで
○ ドメインモデリングの方法
○ ドメインモデルを実装に落とす
○ ライブコーディング
● プロジェクトへの導入方法のススメ
● 「ドメイン駆動設計 モデリング/実装ガイド」他の章の紹介 
話す内容
22
1章より
2章より
3~11章
資料公開
● サンプルコード
○ GitHubにて公開中
● 資料
○ こちらにて公開中
23
今日のゴール
24
● DDDの概要、開発の流れを理解する
今日のゴール
● DDDの概要、開発の流れを理解する
● DDD、そんなに難しくないと思えるようになる
今日のゴール
今日のゴール
● DDDの概要、開発の流れを理解する
● DDD、そんなに難しくないと思えるようになる
● 顿顿顿についてもっと知りたくなる
DDDとは
28
DDDとは
● DDDとは
DDDとは
● DDDとは
抽象的にいうと「ソフトウェア開発手法の一つ」である
● そもそも、ソフトウェアはなんのために作るのか?
● ソフトウェアを適用する対象の何らかの問題を解決するため
● この「ソフトウェアで問題解決しようとする対象」を「ドメイン」と呼ぶ
● DDD:
DomainDrivenDesign(ドメイン駆動設計)の略
● DDD Referenceより
"多くのプロジェクトは、モデリングを行っても
最終的に大きな利益を得られないまま終わります。
DDDは、モデリングから劇的な利益を得られたプロジェクトから、
成功するパターンを抽出します。”
(注:DDD Reference)
DomainLanguage.comにあるDDDのエッセンスの要約版
Evans本よりだいぶまとまっているので、定義などに迷ったらまずこちらを参考に
● DDD:
DomainDrivenDesign(ドメイン駆動設計)の略
● DDD Referenceより
"多くのプロジェクトは、モデリングを行っても
最終的に大きな利益を得られないまま終わります。
DDDは、モデリングから劇的な利益を得られたプロジェクトから、
成功するパターンを抽出します。”
● DDDは
「ドメインモデリングによってソフトウェアの価値を高める」
ことを目指す。
あれ?
あれ?
アーキテクチャ、コード品質の話が出てこない?
「コード品質を上げること」を目的としてDDDを導入検討されることが多いですが
DDDの目的はコード品質のさらに先にあるのです
では、コード品質との関係はどうなるのか?
今日はそのつながりも含んだ全体像を示します。
● 「モデル」とはなんでしょうか?
モデルって何?
モデルとは?に対する様々な答え
● DBA
「DBのテーブルのこと」
43
● DBA
「DBのテーブルのこと」
● サーバーサイドエンジニア
「テーブルに対応したオブジェクトのこと」
モデルとは?に対する様々な答え
44
モデルとは?に対する様々な答え
● DBA
「DBのテーブルのこと」
● サーバーサイドエンジニア
「テーブルに対応したオブジェクトのこと」
● 機械学習エンジニア
「数式のこと」
45
モデルとは?
● 「モデル」という言葉は文脈によって大きく違う使われ方をする
● 言葉の定義をしましょう
● model:
A system of abstractions that describes selected aspects of a domain and can
be used to solve problems related to that domain
● モデル:問題解決のために、物事の特定の側面を抽象化したもの
DDD文脈での定義
ざっくり意訳
47
モデルの区別
● ドメインモデル:
● データモデル:
48
モデルの区別
● ドメインモデル:
ドメインの問題を解決するためのモデル
● データモデル:
49
モデルの区別
● ドメインモデル:
ドメインの問題を解決するためのモデル
● データモデル:
データベースに何かを永続化するためのモデル
50
モデルの区別
● ドメインモデル:
ドメインの問題を解決するためのモデル
● データモデル:
データベースに何かを永続化するためのモデル
→ これらは別のものであり、明確に区別する必要がある
51
● モデル:問題解決のために、物事の特定の側面を抽象化したもの
→ 抽象化とは何でしょうか?
DDD文脈での定義
52
例:履歴书
例:履歴书 現実には数多くの要素がある
?名前、経歴、志望理由
?写真
例:履歴书 現実には数多くの要素がある
?名前、経歴、志望理由
?写真
?筆跡、筆圧
?紙質、折れ具合
例:履歴书 現実には数多くの要素がある
?名前、経歴、志望理由
?写真
?筆跡、筆圧
?紙質、折れ具合
?履歴書のメーカー
?履歴書の値段
?履歴書を書いた時の気持ち
?:
现実世界の全ての要素をソフトウェアに落とし込むことは不可能
现実世界の全ての要素をソフトウェアに落とし込むことは不可能
→ 必要な要素はモデルに取り込みたい
→ 不要な要素はモデルに取り込みたくない
现実世界の全ての要素をソフトウェアに落とし込むことは不可能
→ 必要な要素はモデルに取り込みたい
→ 不要な要素はモデルに取り込みたくない
この選択が「抽象化」
● 良いモデルとは何か?
● 良いモデルとは何か?
わかりやすいモデル、現実に即しているモデル、拡張性のあるモデル…
● 良いモデルとは何か?
わかりやすいモデル、現実に即しているモデル、拡張性のあるモデル…
→問題解決ができるモデル
● 良いモデルとは何か?
わかりやすいモデル、現実に即しているモデル、拡張性のあるモデル…
→問題解決ができるモデル
● 良くないモデルとは何か?
● 良いモデルとは何か?
わかりやすいモデル、現実に即しているモデル、拡張性のあるモデル…
→問題解決ができるモデル
● 良くないモデルとは何か?
→問題解決ができないモデル
○ 現実に即していない
○ やりたいことができない
● 中途採用における「採用進捗」
現実世界(ドメイン) モデル
● 中途採用における「採用進捗」
現実世界(ドメイン) モデル
● 中途採用における「採用進捗」
現実世界(ドメイン) モデル
書類選考の前に面談
があるのに???
● 中途採用における「採用進捗」
現実世界(ドメイン) モデル
書類選考の前に面談
があるのに???
面接は3次、4次もある
のに???
● 中途採用における「採用進捗」
現実世界(ドメイン) モデル
書類選考の前に面談
があるのに???
面接は3次、4次もある
のに???
求人関係ない応募も
許可したい???
● 中途採用における「採用進捗」
現実世界(ドメイン) モデル
書類選考の前に面談
があるのに???
面接は3次、4次もある
のに???
求人関係ない応募も
許可したい???
運用で
カバー
技术の败北感がある
モデルが良くなくて问题解决できない
運用でカバーできればまだマシ、
売れなければプロダクトがなくなる
● もしも、このソフトウェアが
● もしも、このソフトウェアが
● DDDの実装パターンを的確に使っている
● コードの可読性、拡張性が完璧
● テストも完璧で、バグが全くでない
● もしも、このソフトウェアが
● DDDの実装パターンを的確に使っている
● コードの可読性、拡張性が完璧
● テストも完璧で、バグが全くでない
 ものだったとしたら、高い価値を生み出せるか?
● もしも、このソフトウェアが
● DDDの実装パターンを的確に使っている
● コードの可読性、拡張性が完璧
● テストも完璧で、バグが全くでない
 ものだったとしたら、高い価値を生み出せるか?
→ NO!!
● モデルがイケてないと、
その後の実装がどんなに素晴らしくても良いソフトウェアにはならない
● 良いモデルを作るにはどうすれば良いか?
● 良いモデルを作るにはどうすれば良いか?
→ドメインに詳しい人から知識を得る
● 良いモデルを作るにはどうすれば良いか?
→ドメインに詳しい人から知識を得る
→運用した知見をモデルにフィードバックして改善する
● 良いモデルを作るにはどうすれば良いか?
→ドメインに詳しい人から知識を得る
→運用した知見をモデルにフィードバックして改善する
→モデルは最初から完成しない、改善していくもの
 (DDDとして重要なスタンス)
● モデルは最初から完成しない、改善していくもの
モデル コード
● モデルは最初から完成しない、改善していくもの
モデル コード
● コードとモデルが乖離すると…
モデル コード
● コードとモデルが乖離すると…
○ モデルの更新をコードに正しく反映できているかわからなくなる
モデル コード
● コードとモデルが乖離すると…
○ モデルの更新をコードに正しく反映できているかわからなくなる
○ モデルからコードを理解しにくくなる
モデル コード
● モデルの更新をコードに正しく反映できているかわからない
● コードからモデルを理解しにくい
モデルとコードが乖離すると発生する問題
● モデルの更新をコードに正しく反映できているかわからない
→意図していない実装(=バグ)を産みやすくなる
● コードからモデルを理解しにくい
モデルとコードが乖離すると発生する問題
● モデルの更新をコードに正しく反映できているかわからない
→意図していない実装(=バグ)を産みやすくなる
● コードからモデルを理解しにくい
→ドメインに対する理解もできない
→モデルは改善されない
→ソフトウェアの価値を高めにくくなる
モデルとコードが乖離すると発生する問題
● コードとモデルが乖離すると問題が発生する
● モデルは継続的に改善したい
問題と対策
● コードとモデルが乖離すると問題が発生する
→モデルそのまま表現したコードとなるのが望ましい
● モデルは継続的に改善したい
問題と対策
● コードとモデルが乖離すると問題が発生する
→モデルそのまま表現したコードとなるのが望ましい
→「オブジェクト」でモデルを表現する
● モデルは継続的に改善したい
問題と対策
● コードとモデルが乖離すると問題が発生する
→モデルそのまま表現したコードとなるのが望ましい
→「オブジェクト」でモデルを表現する
● モデルは継続的に改善したい
→コードにも継続的に反映しないと行けない
→頻繁な変更に耐えうるには、拡張性の高い設計が必要
問題と対策
● コードとモデルが乖離すると問題が発生する
→モデルそのまま表現したコードとなるのが望ましい
→「オブジェクト」でモデルを表現する
● モデルは継続的に改善したい
→コードにも継続的に反映しないと行けない
→頻繁な変更に耐えうるには、拡張性の高い設計が必要
→これはソフトウェアとしては非常に高い要求
問題と対策
● コードとモデルが乖離すると問題が発生する
→モデルそのまま表現したコードとなるのが望ましい
→「オブジェクト」でモデルを表現する
● モデルは継続的に改善したい
→コードにも継続的に反映しないと行けない
→頻繁な変更に耐えうるには、拡張性の高い設計が必要
→これはソフトウェアとしては非常に高い要求
→そこで生まれたのがEntityやRepositoryなどのデザインパターン
問題と対策
● 軽量DDD:DDDの実装パターンだけ取り入れること
軽量DDDとは
● 軽量DDD:DDDの実装パターンだけ取り入れること
● 拡張性の高いベストプラクティスを取り入れる
→それだけでも十分価値がある
軽量DDDとは
● 軽量DDD:DDDの実装パターンだけ取り入れること
● 拡張性の高いベストプラクティスを取り入れる
→それだけでも十分価値がある
● コード品質をあげると、ようやくモデリングする余地が生まれる
と考えることもできる
軽量DDDとは
● 軽量DDD:DDDの実装パターンだけ取り入れること
● 拡張性の高いベストプラクティスを取り入れる
→それだけでも十分価値がある
● コード品質をあげると、ようやくモデリングする余地が生まれる
と考えることもできる
● 何の問題もない、
そこからモデリングに踏み出しましょう
軽量DDDとは
DDDのアプローチ
DDDのアプローチの全体像
DDDのアプローチ
モデルがイケてないと、
実装がどんなに素晴らしくても良いソフトウェアにはならない
DDDのアプローチ
モデルを継続的にソフトウェアに反映するために拡張性の高い設計をする
どうやってモデリングするのか
104
ドメインモデリングの方法
● 一つに決まった方法はない
○ 体系化された手法の例
■ リレーションシップ駆動要件分析(RDRA)
■ ユースケース駆動分析設計
● シンプルな例をご紹介
ユースケース図 / ドメインモデル図によるモデリング
● タスク管理アプリケーションにおける事例で説明する
105
ユースケース図
● ユーザーとアプリケーションの相互作用を定義する
● 一般的なUMLのものと同じ
106
ユースケース図
● ユーザーとアプリケーションの相互作用を定義する
● 一般的なUMLのものと同じ
107
ユースケース図
● ユーザーとアプリケーションの相互作用を定義する
● 一般的なUMLのものと同じ
● 次に続くドメイン図作成の範囲も決める
今回のモデリングのス
コープ
108
● ユースケースの具体化?言語化
○
● ドメインモデル図作成作業の範囲を狭める
○
ユースケース図を作る必要性
109
● ユースケースの具体化?言語化
○ 具体化しないと、どのようなモデルを作ればいいかわからない
○ 「いち作業者として、自分のタスクを管理したい」のか
「管理者として、複数作業者のタスク状況を管理したい」のか
それによって「タスク」のドメインモデルは違うものになる
● ドメインモデル図作成作業の範囲を狭める
○
ユースケース図を作る必要性
110
● ユースケースの具体化?言語化
○ 具体化しないと、どのようなモデルを作ればいいかわからない
○ 「いち作業者として、自分のタスクを管理したい」のか
「管理者として、複数作業者のタスク状況を管理したい」のか
それによって「タスク」のドメインモデルは違うものになる
● ドメインモデル図作成作業の範囲を狭める
○ ドメインモデル図作成をしていると、いろんな要素が思い浮かんでくる
○ 範囲を限定して、限られた時間でまとまった成果を出せるようにする
ユースケース図を作る必要性
111
ドメインモデル図
● クラス図の簡易版
● メソッド(振る舞い)は不要
● 属性も代表的なものだけでOK
● 業務の「ルール?制約」(=ドメイン知識) を吹き出しで記述する
● 集約の範囲を明記する
112
集約について
● 集約=「必ず守りたい強い整合性を持ったオブジェクトのまとまり」
● 必ずまとめて取得して、まとめて更新する単位
● 今回の発表では集約の検討が必要な事例は示せないが、
「このタイミングで集約設計する」ということを覚えておいてください
113
実際のモデリング
● 最初はホワイトボードに殴り書きでOK
114
ドメインモデル図
115
どうやってコードに落とすか
116
まず、形から入る
● レイヤーを定義して「このレイヤにはこういうクラスを作る」というのを決める
● その決まりの上で、とりあえず動くものを書く
● 参考:新卒にも伝わるドメイン駆動設計のアーキテクチャ説明
117
● 改善余地があるコードから入り、リファクタリングしていきます
説明の流れ
118
● この段階では属性の定義のみ、ドメイン知識は持っていない
Taskクラス
119
TaskApplicationSericeクラス -タスクを登録する
● ApplicationServiceクラスにタスク登録時の処理を書く
120
● 延期時の処理も同様
TaskApplicationSericeクラス -タスクを延期する
121
このコードの問題点
● 不整合なデータをいくらでも作れる
● 仕様を追いかけるのに、複数クラスをコード参照から追っていくしかない
122
ドメインモデル図の見直し
● ドメインモデル図の吹き出しの知識はどのクラスに書かれているか?
123
TaskApplicationSericeクラス -タスクを登録する
タスクは未完了状態で作成
される
124
TaskApplicationSericeクラス -タスクを延期する
タスクは3回だけ、
1日ずつ延期することができる。
125
● ドメインモデル図の知識がApplication層のクラスに書かれている
タスクは未完了状態で作成
される
タスクは3回だけ、
1日ずつ延期することができる。
126
● ドメインモデル図の知識をDomain層のクラス、
特に吹き出しが書かれたオブジェクトに委譲する
タスクは未完了状態で作成
される
タスクは3回だけ、
1日ずつ延期することができる。 127
● 修正前のクラスを再度確認
● このクラスに、吹き出しの知識を委譲する
Taskクラス -Before
128
Taskクラス -After (1/3) コンストラクタ
● コンストラクタにタスク作成時の知識を移譲
タスクは未完了状態で作成
される
129
Taskクラス -After (2/3) 延期メソッド
● 延期メソッドに延期時の知識を移譲
タスクは3回だけ、
1日ずつ延期することができる。
130
Taskクラス -After (3/3) Setter
● Setterがなくなっているので、公開しているメソッド以外で操作できない
131
シンプルになったApplicationServiceクラス
● ユースケース記述レベルの抽象度の高いコードのみ残る
132
この設計のメリット(1/3)
● 不整合なデータを作れないように強制できる
○ Setter非公開にしたので不整合な値をセットできない
コンパイルエラーになる
133
この設計のメリット(2/3)
● 他のルールで生成?更新
されないことが確実になっている
● 1クラスに吹き出しの知識が
凝縮されている
→「このクラスだけ見れば良い」
という大きな安心感を得られる
134
この設計のメリット(3/3)
● レイヤーによって書くべきことが決まっている
→コード規約の様に定めて、
 実装やレビューの時に使える
● 「俺の考えた最強の設計」同士が戦わなくて済む
135
どうやって現場で実践するか
136
● お手本コードを作る
○ ApplicationService、Entity、Repository???
● お手本に倣ってコードを書くようにチーム展開する
○ この段階では軽量DDDでも全然OK
● 「あれ、ドメイン層には何を書くべきなんだっけ?」
となったら、ドメインモデリングしてみる
● ドメインモデル図を元にリファクタリングしていく
DDD導入の進め方
137
● 「原理を理解して実践」より、
「お手本を元に展開」の方が圧倒的に難易度が低いため
●
●
なぜお手本コード展開から入るのか
138
● 「原理を理解して実践」より、
「お手本を元に展開」の方が圧倒的に難易度が低いため
● ドメイン層に何を書くべきか?という疑問を持った方が
モデリングの必要性を感じやすいため
●
なぜお手本コード展開から入るのか
139
なぜお手本コード展開から入るのか
● 「原理を理解して実践」より、
「お手本を元に展開」の方が圧倒的に難易度が低いため
● ドメイン層に何を書くべきか?という疑問を持った方が
モデリングの必要性を感じやすいため
● 「どういうコードに落としこまれるのか」が
イメージできてからの方が、ドメインモデリングしやすいため
140
上達のイメージ
● DDDのコーディング、モデリング共に1発では上手くできない
コーディング モデリング
141
上達のイメージ
● DDDのコーディング、モデリング共に1発では上手くできない
● コーディングだけ、モデリングだけ上手くなるということもない
コーディング モデリング
142
上達のイメージ
● DDDのコーディング、モデリング共に1発では上手くできない
● コーディングだけ、モデリングだけ上手くなるということもない
● 両方交互に経験値をためながら上達していくしかない
コーディング モデリング
143
上達のイメージ
● DDDのコーディング、モデリング共に1発では上手くできない
● コーディングだけ、モデリングだけ上手くなるということもない
● 両方交互に経験値をためながら上達していくしかない
● 結局、このサイクルのどちらから入るか、という違いだけ
コーディング モデリング
144
上達のイメージ
● DDDのコーディング、モデリング共に1発では上手くできない
● コーディングだけ、モデリングだけ上手くなるということもない
● 両方交互に経験値をためながら上達していくしかない
● 結局、このサイクルのどちらから入るか、という違いだけ
● コーディングと、モデリングを意識的に両方少しずつやってみるのが良い
コーディング モデリング
145
まとめ
● DDDでは、「モデルを継続的に改善」「モデルの更新をソフトウェアに反映」のアプロー
チでソフトウェアの価値を高める
● モデルの更新を反映しやすいように、モデルをそのまま表現する
その際にオブジェクト指向の手法を利用する
● DDD戦術設計パターンは、保守性の高い設計のベストプラクティス
● 設計パターンの適用(軽量DDD)と、モデリングを両方使うと、
ソフトウェアの価値を高められる
● 実装と、モデリングを少しずつ着手してみよう
146
他の章の紹介
147
他の章の紹介
148
他の章にも興味を持っていただけた方は
149
「ドメイン駆動設計 モデリング/実装ガイド」
boothにて販売中
質問箱で質問募集しています
● 質問いただければ回答します
● https://peing.net/ja/little_hands
● 「質問箱 little_hands」で検索
150
ご静聴ありがとうございました
151
sli.do回答タイム
152
ご静聴ありがとうございました
153

More Related Content

ドメイン駆動設計 モデリング_実装入門勉强会_2020.3.8