Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

ボトムアップドメイン駆動設計 前編

8.610 Aufrufe

Veröffentlicht am

# URL
後編: https://www.slideshare.net/MasanobuNaruse/bottomup-ddd-2
解説記事: https://nrslib.com/bottomup-ddd/
勉強会情報: https://ddd-community-jp.connpass.com/event/103428/

# 概要
2018/10/23 GMO Yours で行われた「ボトムアップドメイン駆動設計の登壇資料」前編です
口頭での解説前提のためわかりづらい部分もあるかと思いますがご了承ください。

Veröffentlicht in: Technologie
  • Als Erste(r) kommentieren

ボトムアップドメイン駆動設計 前編

  1. 1. ボトムアップ ドメイン駆動設計 成瀬 允宣2018/10/23 in GMO Yours 1
  2. 2. 自己紹介 • 成瀬 允宣 - Masanobu Naruse • プログラマ • C#, Scala, Typescript • DDD とかアーキテクチャの話が好きです • @nrslib • https://nrslib.com 2
  3. 3. もくじ • はじめに • 値オブジェクト • エンティティ • ドメインサービス • リポジトリ • アプリケーションサービス • ファクトリ • トランザクション • 集約 • アーキテクチャ • ドメイン駆動設計への誘い 3
  4. 4. はじめに 4 読んだ方はいらっしゃいますか
  5. 5. はじめに 5 読み切った方はいらっしゃいますか
  6. 6. はじめに 6 理解した方はいらっしゃいますか
  7. 7. はじめに | 辛さの原因 7 辛さの原因 何だろう
  8. 8. はじめに | 辛さの原因 8 ユビキタス言語
  9. 9. はじめに | 辛さの原因 9 ユビキタス言語 ドメインエキスパート
  10. 10. はじめに | 辛さの原因 10 ユビキタス言語 ドメインエキスパート エンティティ
  11. 11. はじめに | 辛さの原因 11 ユビキタス言語 ドメインエキスパート エンティティ 値オブジェクト
  12. 12. はじめに | 辛さの原因 12 ユビキタス言語 ドメインエキスパート エンティティ 値オブジェクト ドメインサービス
  13. 13. はじめに | 辛さの原因 13 ユビキタス言語 ドメインエキスパート エンティティ 値オブジェクト ドメインサービス アプリケーションサービス
  14. 14. はじめに | 辛さの原因 14 ユビキタス言語 ドメインエキスパート エンティティ 値オブジェクトリポジトリ ファクトリ ドメインサービス アプリケーションサービス 集約
  15. 15. 集約 はじめに | 辛さの原因 15 ユビキタス言語 ドメインエキスパート エンティティ 値オブジェクト ドメインサービス アプリケーションサービス リポジトリ ファクトリ 怖い
  16. 16. はじめに | 辛さの原因 16 ドメイン駆動設計は 要するにオブジェクト指向 怖がられて敬遠されるのは勿体ない
  17. 17. はじめに | 辛さの原因 17 怖い ?= 辛さの原因 = ? こと だらけ
  18. 18. はじめに | 辛さの原因 18 怖い 知らない= 辛さの原因 = 知らないこと だらけ
  19. 19. はじめに | 用語 19 用語
  20. 20. はじめに | 用語 20 用語
  21. 21. はじめに | 用語 21 マインド パターン 用語
  22. 22. はじめに | 用語 22 マインド パターン 感じるしかない 用語
  23. 23. はじめに | 用語 23 マインド パターン 感じるしかない 実装できる 用語
  24. 24. はじめに | 用語 24 用語と実装がイメージできれば 辛さは半分になるのでは?
  25. 25. はじめに | 用語 25 いきなり全容を説明しても 辛いから ボトムアップに解説したら 役に立ちそう
  26. 26. はじめに | 用語 26 いきなり全容を説明しても 辛いから ボトムアップに解説したら 役に立ちそう と考えて早一年 書籍化依頼こないかなー・・・ とか漠然と思ってました
  27. 27. はじめに | 記事 ボトムアップドメイン駆動設計 27 https://nrslib.com/bottomup-ddd/ https://nrslib.com/bottomup-ddd-2/ というわけで解説記事にしてみた
  28. 28. はじめに | 記事 ボトムアップドメイン駆動設計 28 https://nrslib.com/bottomup-ddd/ https://nrslib.com/bottomup-ddd-2/ というわけで解説記事にしてみた そもそもこの解説記事が辛い
  29. 29. はじめに | 記事 ボトムアップドメイン駆動設計 29 https://nrslib.com/bottomup-ddd/ https://nrslib.com/bottomup-ddd-2/ というわけで解説記事にしてみた そもそもこの解説記事が辛い
  30. 30. はじめに | 趣旨 30 今回のセミナーの趣旨
  31. 31. はじめに | 趣旨 31 イントロダクションはセミナーで 今回のセミナーの趣旨
  32. 32. はじめに | 趣旨 32 イントロダクションはセミナーで 細かい部分は記事で 今回のセミナーの趣旨
  33. 33. はじめに | 趣旨 33 イントロダクションはセミナーで 細かい部分は記事で マインドは書籍で 今回のセミナーの趣旨
  34. 34. はじめに | ゴール 34 ゴール Evans の本を読む下地を作る
  35. 35. 値オブジェクト 35 最初のお題は 値オブジェクト
  36. 36. 値オブジェクト 36 値って何ですか
  37. 37. 値オブジェクト 37 例えば数値
  38. 38. 値オブジェクト 38
  39. 39. 値オブジェクト 39 ここは何していますか
  40. 40. 値オブジェクト 40 例えば文字列
  41. 41. 値オブジェクト 41
  42. 42. 値オブジェクト 42 ここは何していますか
  43. 43. 値オブジェクト 43 値の変更は代入
  44. 44. 値オブジェクト 44 値の変更は代入 こんなことはしない
  45. 45. 値オブジェクト 45 じゃあ 値を示すオブジェクトも 値らしくしよう
  46. 46. 値オブジェクト 46 じゃあ 値を示すオブジェクトも 値らしくしよう 値オブジェクト
  47. 47. 値オブジェクト | 値の性質 47 状態を不変に保つ 値同士の比較ができる 完全に交換可能である 値の性質
  48. 48. 値オブジェクト | 状態を不変に保つ 48 状態を不変に保つ 値同士の比較ができる 完全に交換可能である 値の性質
  49. 49. 値オブジェクト | 状態を不変に保つ 49 状態とは?
  50. 50. 値オブジェクト | 状態を不変に保つ 50 状態 フィールド=
  51. 51. 値オブジェクト | 状態を不変に保つ 51
  52. 52. 値オブジェクト | 状態を不変に保つ 52 これらがダメなら
  53. 53. 値オブジェクト | 状態を不変に保つ 53 これらがダメなら
  54. 54. 値オブジェクト | 状態を不変に保つ 54 これもダメ これらがダメなら
  55. 55. 値オブジェクト | 状態を不変に保つ 55
  56. 56. 値オブジェクト | 状態を不変に保つ 56 値の変更は代入
  57. 57. 値オブジェクト | 状態を不変に保つ 57 値の変更は代入で
  58. 58. 値オブジェクト | 状態を不変に保つ 58 メリット 不変であることそれ自体 ・可変な状態は取り扱いが難しい ・並行/並列処理では特に難しい ・バグの温床
  59. 59. 値オブジェクト | 値同士の比較ができる 59 値の性質 状態を不変に保つ 値同士の比較ができる 完全に交換可能である
  60. 60. 値オブジェクト | 値同士の比較ができる 60 値の比較の仕方は?
  61. 61. 値オブジェクト | 値同士の比較ができる 61 値の比較の仕方は?
  62. 62. 値オブジェクト | 値同士の比較ができる 62 値の比較の仕方は? こうは書かない
  63. 63. 値オブジェクト | 値同士の比較ができる 63 じゃあ値オブジェクトも こう書かない
  64. 64. 値オブジェクト | 値同士の比較ができる 64 値のように表現すべき
  65. 65. 値オブジェクト | 値同士の比較ができる 65 比較のための実装
  66. 66. 値オブジェクト | 値同士の比較ができる 66 比較のための実装
  67. 67. 値オブジェクト | 値同士の比較ができる 67 Snipet や Resharper などの Tool で生成 比較のための実装
  68. 68. 値オブジェクト | 値同士の比較ができる 68 メリット 値の変更箇所の集約
  69. 69. 値オブジェクト | 値同士の比較ができる 69 変更してみよう 属性比較版 比較メソッド版
  70. 70. 値オブジェクト | 値同士の比較ができる 70 値に属性を追加 変更してみよう 属性比較版 比較メソッド版
  71. 71. 値オブジェクト | 値同士の比較ができる 71 値に属性を追加 変更してみよう 属性比較版 比較メソッド版
  72. 72. 値オブジェクト | 値同士の比較ができる 72 値に属性を追加 変更してみよう 属性比較版 比較メソッド版
  73. 73. 値オブジェクト | 値同士の比較ができる 73 状態を不変に保つ 値同士の比較ができる 完全に交換可能である 値の性質
  74. 74. 値オブジェクト | 完全に交換可能である 74 復習
  75. 75. 値オブジェクト | 完全に交換可能である 75 Q. 値の変更を行う方法は? 復習
  76. 76. 値オブジェクト | 完全に交換可能である 76 Q. 値の変更を行う方法は? 復習 A. 代入
  77. 77. 値オブジェクト | 完全に交換可能である 77 代入って要するに 交換
  78. 78. 値オブジェクト | 完全に交換可能である 78 代入って要するに 交換 値を不変にしたことで 交換以外の 変更の表現手段がなくなった
  79. 79. 値オブジェクト | モチベーション 79 値オブジェクトにするモチベーションは?
  80. 80. 値オブジェクト | 存在しない値を存在させない 80 表現力を増す 存在しない値を存在させない 誤った代入を防ぐ 値オブジェクトのモチベーション
  81. 81. 値オブジェクト | 存在しない値を存在させない 81 表現力を増す 存在しない値を存在させない 誤った代入を防ぐ 値オブジェクトのモチベーション
  82. 82. 値オブジェクト | 存在しない値を存在させない 82 例えば ユーザ名の長さって 最長いくつですか
  83. 83. 値オブジェクト | 存在しない値を存在させない 83 ユーザ名の長さを 50 文字以下とします
  84. 84. 値オブジェクト | 存在しない値を存在させない 84
  85. 85. 値オブジェクト | 存在しない値を存在させない 85 コードで表現
  86. 86. 値オブジェクト | 存在しない値を存在させない 86 コードで表現 50文字を超えるユーザ名という 本来あり得ないものを存在させない
  87. 87. 値オブジェクト | 誤った代入を防ぐ 87 表現力を増す 存在しない値を存在させない 誤った代入を防ぐ 値オブジェクトのモチベーション
  88. 88. 値オブジェクト | 誤った代入を防ぐ 88 代入を間違えたこと ありますか?
  89. 89. 値オブジェクト | 誤った代入を防ぐ 89 こんなクラス
  90. 90. 値オブジェクト | 誤った代入を防ぐ 90 こんなクラス こんなメソッドと
  91. 91. 値オブジェクト | 誤った代入を防ぐ 91 こんなクラス こんなメソッドと Id に name を代入してるけど 正しい?
  92. 92. 値オブジェクト | 誤った代入を防ぐ 92 値オブジェクトで表現したら
  93. 93. 値オブジェクト | 誤った代入を防ぐ 93 値オブジェクトで表現したら
  94. 94. 値オブジェクト | 誤った代入を防ぐ 94 値オブジェクトで表現したら
  95. 95. 値オブジェクト | 誤った代入を防ぐ 95 誤った代入が 発生しづらくなる 値オブジェクトで表現したら
  96. 96. エンティティ 96 次のお題は エンティティ
  97. 97. エンティティ 97 エンティティとは 属性ではなく 同一性によって 識別されるモデル
  98. 98. エンティティ 98 エンティティとは 値オブジェクトの逆
  99. 99. エンティティ 99 可変 同じ属性でも区別される 同一性を持つ エンティティの性質
  100. 100. エンティティ | 可変 100 可変 同じ属性でも区別される 同一性を持つ エンティティの性質
  101. 101. エンティティ | 可変 101
  102. 102. エンティティ | 可変 102 名前を変更できるようにしたい
  103. 103. エンティティ | 可変 103
  104. 104. エンティティ | 可変 104 属性が可変
  105. 105. エンティティ | 可変 105 可変 同じ属性でも区別される 同一性を持つ エンティティの性質
  106. 106. エンティティ | 同じ属性でも区別される 106 ユーザ A ユーザ B
  107. 107. エンティティ | 同じ属性でも区別される 107 ユーザ A ユーザ B FirstName: taro FamilyName: tanaka FirstName: taro FamilyName: tanaka
  108. 108. エンティティ | 同じ属性でも区別される 108 ユーザ A ユーザ B FirstName: taro FamilyName: tanaka FirstName: taro FamilyName: tanaka 同じユーザ?
  109. 109. エンティティ | 同じ属性でも区別される 109 同じユーザ?
  110. 110. エンティティ | 同じ属性でも区別される 110 属性が同じでも同姓同名かもしれない
  111. 111. エンティティ | 同じ属性でも区別される 111 ユーザを識別する必要がある 属性が同じでも同姓同名かもしれない
  112. 112. エンティティ | 同じ属性でも区別される 112 識別子が必要 属性が同じでも同姓同名かもしれない ユーザを識別する必要がある
  113. 113. エンティティ | 同じ属性でも区別される 113
  114. 114. エンティティ | 同じ属性でも区別される 114
  115. 115. エンティティ | 同じ属性でも区別される 115 ユーザ A ユーザ B FirstName: taro FamilyName: tanaka Id: A FirstName: taro FamilyName: tanaka Id: B
  116. 116. エンティティ | 同じ属性でも区別される 116 ユーザ A ユーザ B FirstName: taro FamilyName: tanaka Id: A FirstName: taro FamilyName: tanaka Id: B IDで識別できるようになった
  117. 117. エンティティ | 可変 117 可変 同じ属性でも区別される 同一性を持つ エンティティの性質
  118. 118. エンティティ | 同一性を持つ 118 FirstName: taro FamilyName: tanaka
  119. 119. エンティティ | 同一性を持つ 119 FirstName: taro FamilyName: tanaka FirstName: taro FamilyName: sato
  120. 120. 別人? エンティティ | 同一性を持つ 120 FirstName: taro FamilyName: tanaka FirstName: taro FamilyName: sato
  121. 121. 別人? エンティティ | 同一性を持つ 121 FirstName: taro FamilyName: tanaka FirstName: taro FamilyName: sato 同一人物
  122. 122. 別人? エンティティ | 同一性を持つ 122 FirstName: taro FamilyName: tanaka Id: A FirstName: taro FamilyName: sato Id: A 同一人物
  123. 123. エンティティ | 同一性を持つ 123 C# はこんな感じで実装する ※これはツールによる実装
  124. 124. エンティティ | 同一性を持つ 124 結果
  125. 125. エンティティ | まとめ 125 属性ではなく 同一性によって 識別されるモデル ライフサイクルを持っている
  126. 126. ドメインサービス 126 ドメインサービス の話をします
  127. 127. ドメインサービス 127 全ての混乱の原因
  128. 128. ドメインサービス 128 サービスという言葉 全ての混乱の原因
  129. 129. ドメインサービス 129 Web サービス サービス指向アーキテクチャ アプリケーションサービス ドメインサービス マイクロサービス Saas Paas Iaas
  130. 130. ドメインサービス 130 サービスという言葉の付く単語は 世の中にごまんとある
  131. 131. ドメインサービス 131 ドメインサービスは
  132. 132. ドメインサービス 132 ドメインサービスは エンティティや値オブジェクトに 実装するのが自然でない処理を 実装するオブジェクト
  133. 133. ドメインサービス 133 例えばユーザ登録で 「ユーザ名の重複を許さない」 というケース
  134. 134. ドメインサービス 134 エンティティに定義してみよう
  135. 135. ドメインサービス 135 エンティティに定義してみよう
  136. 136. ドメインサービス 136 エンティティに定義してみよう 使ってみる
  137. 137. ドメインサービス 137 使ってみる 自分に問い合わせ?? エンティティに定義してみよう
  138. 138. ドメインサービス 138 チェック専用オブジェクトを作る
  139. 139. ドメインサービス 139 チェック専用オブジェクトを作る
  140. 140. ドメインサービス 140 チェック専用オブジェクトを作る ‘forcheck’ さんって誰?
  141. 141. ドメインサービス 141 つまりこれは エンティティに 実装するのが自然でない処理
  142. 142. ドメインサービス 142 つまりこれは エンティティに 実装するのが自然でない処理 ドメインサービス
  143. 143. ドメインサービス 143 ドメインサービス 実装は後程
  144. 144. ビジネスロジックを組み立てよう 144 最小限のモデリング要素は学んだので ロジックを組み立ててみよう
  145. 145. ビジネスロジックを組み立てよう 145 最小限のモデリング要素は学んだので ロジックを組み立ててみよう お題はユーザ登録
  146. 146. ビジネスロジックを組み立てよう 146
  147. 147. ビジネスロジックを組み立てよう 147 MySQL を使うとしたら
  148. 148. ビジネスロジックを組み立てよう 148 こんな感じ?
  149. 149. ビジネスロジックを組み立てよう 149 きっとドメインサービスも
  150. 150. ビジネスロジックを組み立てよう 150 こうなる きっとドメインサービスも
  151. 151. ビジネスロジックを組み立てよう 151 データベースは大事
  152. 152. ビジネスロジックを組み立てよう 152 だけど
  153. 153. ビジネスロジックを組み立てよう 153 ユーザ登録処理という ロジックの大半を 占めるべき内容か
  154. 154. リポジトリ 154 そこで リポジトリの出番です
  155. 155. リポジトリ 155 リポジトリは
  156. 156. リポジトリ 156 リポジトリは データの永続化を担う オブジェクト
  157. 157. リポジトリ 157 リポジトリは データの永続化を担う オブジェクト 永続化の対象 =
  158. 158. リポジトリ 158 リポジトリは データの永続化を担う オブジェクト 永続化の対象 = エンティティ
  159. 159. リポジトリ 159 リポジトリを作ってみよう
  160. 160. リポジトリ 160
  161. 161. リポジトリ 161 永続化装置からの再構築(検索)
  162. 162. リポジトリ 162 永続化装置からの再構築(検索) 永続化
  163. 163. リポジトリ 163
  164. 164. リポジトリ 164 すっきり
  165. 165. リポジトリ 165 きっとドメインサービスも
  166. 166. リポジトリ 166 きっとドメインサービスも こうなる
  167. 167. リポジトリ 167 結果として こうなる
  168. 168. リポジトリ | テスト 168 ところでテストって好きですか?
  169. 169. リポジトリ | テスト 169 どうやってテストする?
  170. 170. リポジトリ | テスト 170 どうやってテストする?
  171. 171. リポジトリ | テスト 171 どうやってテストする? データベースに接続
  172. 172. リポジトリ | テスト 172 どうやってテストする? データベースにデータを用意する・・・ データベースに接続
  173. 173. リポジトリ | テスト 173 ここからがリポジトリの 本領発揮です
  174. 174. リポジトリ | テスト 174 まずはリポジトリの インターフェースを用意 ※インターフェースがない言語は完全抽象クラスで
  175. 175. リポジトリ | テスト 175 本番用リポジトリはインターフェースを実装
  176. 176. リポジトリ | テスト 176 テストのためのリポジトリを用意
  177. 177. リポジトリ | テスト 177 さっきのロジックは
  178. 178. リポジトリ | テスト 178 こうなる
  179. 179. リポジトリ | テスト 179
  180. 180. リポジトリ | テスト 180
  181. 181. リポジトリ | テスト 181 InMemoryUserRepository or UserRepository
  182. 182. リポジトリ | テスト 182 InMemoryUserRepository or UserRepository
  183. 183. リポジトリ | テスト 183 InMemoryUserRepository or UserRepository
  184. 184. リポジトリ | テスト 184 このロジックは依存がなくなった
  185. 185. リポジトリ | テスト 185 このロジックは依存がなくなった 依存 =
  186. 186. リポジトリ | テスト 186 このロジックは依存がなくなった UserRepository への依存 特定のインフラへの依存依存 =
  187. 187. リポジトリ | 純粋なロジックとして 187 InMemoryUserRepository に 再現したいデータを用意しておけば テストができる
  188. 188. リポジトリ | 純粋なロジックとして 188 InMemoryUserRepository に 再現したいデータを用意しておけば テストができる 特定の具象オブジェクトに依存しないので 本番と同じロジックを使ってテストができる
  189. 189. アプリケーションサービス 189 次のテーマは アプリケーションサービス
  190. 190. アプリケーションサービス 190 アプリケーションサービスは ビジネスロジックの API
  191. 191. アプリケーションサービス 191 アプリケーションサービスは ビジネスロジックの API 何ができるかを表現
  192. 192. アプリケーションサービス 192 ユースケースを表現
  193. 193. アプリケーションサービス 193
  194. 194. アプリケーションサービス 194 どこかで見たことが ありませんか
  195. 195. アプリケーションサービス 195 これまで出てきた Program クラスは 実はアプリケーションサービス
  196. 196. アプリケーションサービス 196 アプリケーションサービスは
  197. 197. アプリケーションサービス 197 エンティティ 値オブジェクト ドメインサービス リポジトリ アプリケーションサービスは
  198. 198. アプリケーションサービス 198 エンティティ 値オブジェクト ドメインサービス リポジトリ これらを協調させて ユースケースを達成する アプリケーションサービスは
  199. 199. アプリケーションサービス 199 ユースケースが達成できる
  200. 200. アプリケーションサービス 200 ユースケースが達成できる アプリが作れる
  201. 201. アプリケーションサービス | MVC 201 MVC フレームワークに組み込もう
  202. 202. アプリケーションサービス | MVC 202
  203. 203. アプリケーションサービス | MVC 203 DI
  204. 204. アプリケーションサービス | DI 204 Dependency Injection
  205. 205. アプリケーションサービス | DI 205 Dependency Injection 依存しているオブジェクトを コンストラクタで設定する
  206. 206. アプリケーションサービス | DI 206 Dependency Injection 依存しているオブジェクトを コンストラクタで設定する
  207. 207. アプリケーションサービス | DI 207 MVC フレームワークでは Controller のコンストラクタは フレームワークが呼び出しを行うので DIContainer を利用して 依存を設定する
  208. 208. アプリケーションサービス | DI 208 こんな感じ
  209. 209. アプリケーションサービス | セパレートインターフェース 209 ところでこんな風に interface を 用意する場合もあります
  210. 210. アプリケーションサービス | セパレートインターフェース 210 ところでこんな風に interface を 用意する場合もあります セパレートインターフェース と言われます
  211. 211. アプリケーションサービス | セパレートインターフェース 211 ところでこんな風に interface を 用意する場合もあります
  212. 212. アプリケーションサービス | セパレートインターフェース 212 ところでこんな風に interface を 用意する場合もあります
  213. 213. アプリケーションサービス | セパレートインターフェース 213 なんのために?
  214. 214. アプリケーションサービス | セパレートインターフェース 214 例えば例外が発生したときの動作を チェックしたい
  215. 215. アプリケーションサービス | セパレートインターフェース 215 例えば例外が発生したときの動作を チェックしたい インメモリのリポジトリでも 例外を起こすような 整合性のあるデータを 用意するのは大変・・・
  216. 216. アプリケーションサービス | セパレートインターフェース 216 セパレートインターフェースにしておけば
  217. 217. アプリケーションサービス | セパレートインターフェース 217 データを準備しなくても 例外を投げるオブジェクトに差し替えれる セパレートインターフェースにしておけば
  218. 218. 閑話休題 218 アプリケーションが 作れるようになりました ここから後半です

×