Successfully reported this slideshow.
Your SlideShare is downloading. ×

ドメイン駆動設計という設計スタイル

Ad

ドメイン駆動設計という
設計スタイル
ギルドワークス 増田 亨
2019.8.31
レガシーをぶっつぶせ! 現場でDDD #genbadeDDD

Ad

これから話すこと
2019/8/31 2
設計スタイルの選択
ドメインロジックに焦点をあわせる
開発現場での実験結果と考察

Ad

設計スタイルの選択
32019/8/31

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Loading in …3
×

Check these out next

1 of 63 Ad
1 of 63 Ad
Advertisement

More Related Content

More from 増田 亨 (20)

Advertisement

ドメイン駆動設計という設計スタイル

  1. 1. ドメイン駆動設計という 設計スタイル ギルドワークス 増田 亨 2019.8.31 レガシーをぶっつぶせ! 現場でDDD #genbadeDDD
  2. 2. これから話すこと 2019/8/31 2 設計スタイルの選択 ドメインロジックに焦点をあわせる 開発現場での実験結果と考察
  3. 3. 設計スタイルの選択 32019/8/31
  4. 4. 設計スタイルの三つの側面 2019/8/31 4 関心の分離のアプローチ モジュール構造の考え方 20:80のとらえ方
  5. 5. 設計スタイルの三つの側面 2019/8/31 5 関心の分離のアプローチ モジュール構造の考え方 20:80のとらえ方 何と何を分けるか? 何と何を一体にするか ソースコードをどう分割し、どう組み立てるか 80%に大きな影響を及ぼす20%はどこか
  6. 6. 設計スタイルの違い 2019/8/31 6 関心 モジュール構造 20:80
  7. 7. 設計スタイルの違い 2019/8/31 7 関心 モジュール構造 20:80 入出力 ドメインロジック
  8. 8. 設計スタイルの違い 2019/8/31 8 関心 モジュール構造 20:80 入出力 ドメインロジック ビジネスルールに基づく計算と判断のロジック画面、テーブル、Web API
  9. 9. 設計スタイルの違い 2019/8/31 9 関心 モジュール構造 20:80 入出力 ドメインロジック ビジネスルールに基づく計算と判断のロジック画面、テーブル、Web API トランザクションスクリプト ドメインオブジェクトモデル
  10. 10. 設計スタイルの違い 2019/8/31 10 関心 モジュール構造 20:80 入出力 ドメインロジック ビジネスルールに基づく計算と判断のロジック画面、テーブル、Web API トランザクションスクリプト 画面やデータに注目して、入出力手続きを構造化 値の種類に注目して、独自の型を定義 ドメインオブジェクトモデル
  11. 11. 設計スタイルの違い 2019/8/31 11 関心 モジュール構造 20:80 入出力 ドメインロジック ビジネスルールに基づく計算と判断のロジック画面、テーブル、Web API トランザクションスクリプト ドメインロジックの設計と実装が アプリケーション全体の構造を左右する 画面やデータに注目して、入出力手続きを構造化 値の種類に注目して、独自の型でロジックを構造化 入出力の設計と実装が アプリケーション全体の構造を左右する ドメインオブジェクトモデル
  12. 12. ドメイン駆動設計の設計スタイル 2019/8/31 12 ビジネスルールに基づく計算と判断のロジック に焦点を合わせる
  13. 13. ドメイン駆動設計の設計スタイル 2019/8/31 13 ビジネスルールに基づく計算と判断のロジック に焦点を合わせる ビジネスルールに登場する値の種類に注目して 独自の型を定義してロジックを整理する
  14. 14. ドメイン駆動設計の設計スタイル 2019/8/31 14 ビジネスルールに基づく計算と判断のロジック に焦点を合わせる ビジネスルールに登場する値の種類に注目して 独自の型を定義してロジックを整理する ビジネスルールを記述する部分の設計と実装が アプリケーション全体の構造と秩序を左右する
  15. 15. ドメインロジックに焦点を合わせる 2019/8/31 15
  16. 16. 2019/8/31 16 ドメインロジックに 焦点を合わせる ドメイン知識のコード表現 継続的な改善 ドメインの知識を 学び続ける 実践する 実践する 相互に補完する
  17. 17. ドメインロジック、ドメインの知識 2019/8/31 17 意味が広く、あいまい もっと具体的に考える ドメインロジック → ビジネスロジック ドメイン知識 → ビジネスルール
  18. 18. 2019/8/31 18 ビジネスの活動 ビジネスルール ビジネスロジック 制約する/促進する ビジネスルールに基づく計算ロジックや判断ロジック ドメインの知識 ドメインロジック
  19. 19. 2019/8/31 19 ビジネスロジック ビジネスルールに基づく計算と判断のロジック
  20. 20. 2019/8/31 20 ビジネスロジックに 焦点を合わせる ビジネスルールの コード表現の工夫と改善 ビジネスルールを 学び続ける 実践する 実践する 相互に補完する
  21. 21. ビジネスルール 2019/8/31 21 ビジネスの活動を制約し促進する決め事 物理法則のような論理的な体系ではない 過去の意思決定の積み重ね 現在のビジネスルール体系は通過点 これからもビジネスルールの追加や変更が続く
  22. 22. ビジネスルールを学び続ける 2019/8/31 22 ビジネスルールの知識を広げると、要求の意味が理解できる ビジネスルールを深く理解すると、関係性や構造が見えてくる 詳細な仕様の補完力と提案力が増す ビジネスとビジネスルールは時間とともに変化し続ける
  23. 23. 現場で役立つビジネスルールの基礎知識 2019/8/31 23 ドメインエキスパートとか、ユビキタス言語とか言う前に
  24. 24. ドメイン層の全体構造を設計する時の指針 2019/8/31 24 文書化(構造化)された ビジネスルール 顧客の利益 vs 自社の利益 折り合いのつけ方の決め事 競争戦略とビジネスルール ビジネスルールの階層構造 こういう基礎的な知識を学び理解すると、ドメイン層のパッケージ構造の設計の質が変わってくる
  25. 25. 文書化(構造化)されたビジネスルール 説明 顧客に向けた取引条件や利用条件の説明 価格表、利用案内、割引、特典、返品・返金、キャンセル、… 契約書 提供の約束、支払いの約束 提供できなかった時の約束、支払いできなかった時の約束 業務マニュアル 販売ポリシー、在庫ポリシー、サービスレベルポリシー、… 役職・権限・承認ルール 簿記・予実管理 売上、費用、利益の目標と実績 管理単位(部門、期間、集計、…) 2019/5/11 25 文書化の範囲や精度は、組織によってまちまち 上場企業(とその子会社)と非上場企業の差は大きい
  26. 26. 顧客の利益 vs 自社の利益 どこで折り合いをつけるかの決め事 Customer Value 顧客価値 提供する商品、提供するサービス内容の決め事 Customer Cost 顧客からみたコスト 価格、値引き、特典にからむビジネスルール Convenience 顧客の利便性 提供方法、提供場所、提供タイミングのビジネスルール Communication 顧客との コミュニケーション 顧客とのコミュニケーションに関するビジネスルール 2019/5/11 26 ビジネスルールは、コストの制限、リスク回避の決め事であることが多い ドメイン層のパッケージ分割の設計パターンのひとつ
  27. 27. 競争戦略とビジネスルール リーダー 強い競争力 大きな経営資源 他のプレーヤーの強みを消すためのビジネスルール変更が多くなる (そういう意味では後追い型の変更) チャレン ジャー 独自優位性に挑戦 大きな経営資源 仮説検証型、企画型のビジネスルール変更が多くなる 新しい商品、新しい販売方法、新しい特典、… フォロワー 弱い競争力 弱い経営資源 生き残りのための後追い型のビジネスルール変更が多くなる 資源がないので、ルール変更も場当たりや中途半端になりがち ニッチャ 独自性が強く 経営資源は小さい 独自性を維持・強化することに集中する ビジネスルールは独自かつ複雑になりがち 選択と集中の意思決定が明確 2019/5/11 27 その事業の競争戦略によって、パッケージの依存関係や中核となるパッケージが変わってくる
  28. 28. ビジネスルールの階層構造 ポリシー 事業運営の決め事 ビジネスルールの方針 価格、割引、優遇、拒絶 オーバーブッキング キャンセル 約束 顧客との契約 取引先との契約 見積 予約 注文 運用 ビジネス活動の実体(イベント) ビジネスルールの起動トリガー 出荷、売り上げ 請求、回収 能力 ビジネス運営上の制約条件 在庫 出荷能力 サービス提供能力 2019/5/11 28 エヴァンス本 責務のレイヤーにも登場する階層構造のパターン
  29. 29. ビジネスルールをコードで表現する 基本テクニック 2019/8/31 29
  30. 30. 2019/8/31 30 ビジネスロジックに 焦点を合わせる ビジネスルールの コード表現の工夫と改善 ビジネスルールを 学び続ける 実践する 実践する 相互に補完する
  31. 31. 2019/8/31 31 ビジネスルールとコード表現 Fact, Rule, Goalを表現する 独自の型を定義する 値の種類に注目する
  32. 32. ビジネスルールの構成要素 Fact 事実を表現する型 ビジネスの状況の記録や通知に使う型 ・ 数値、日付、場所、識別番号、名称、… Rule Factを使った 計算や判定のロジック オブジェクトが持つべき演算能力 ・算術演算 ・同一性の判定 ・大小の比較 Goal 知りたいことを表現する型 計算結果や判定結果を表現する型 ・合計金額、予定日、残数、… ・出荷可否、受付可否、割引種類、… 2019/5/11 32
  33. 33. 独自の型を定義する 2019/8/31 33 型は値の種類(金額、数量、日付、…) 型は値の範囲を制限する 型は可能な操作(演算)を制限する 型はプログラムに構造と秩序をもたらす 型の名前がコードの意図を豊かに表現する
  34. 34. 現場で役立つ独自の型の設計パターン 2019/8/31 34 計算・判断ロジックのカプセル化 条件分岐を明示的に扱う コレクション操作のカプセル化
  35. 35. 値オブジェクト 計算・判断ロジックのカプセル化 単一の値 範囲(fromとto) 数値 金額型 Amount, Money 金額範囲 x円以上 y円未満 数量型 Quantity, NumberOfXxx 数量範囲 m人以上 n人以下 率型 Percentage, Permillage 率範囲 m%以上 n%未満 時間 日付型 DueDate, XxxDate 期間 開始日 - 終了日 時刻型 HourTime, XxxTime 時間 開始時刻 – 終了時刻 空間 地点型 Point 接続 Path:出発点 – 到達点 2019/5/11 35
  36. 36. 計算の種類 説明、メソッド例 結果の型 等値判定 isEqual( other ) , notEqual( other ) boolean / enum 大小判定 greaterThan( other ), lessThan( other ), … boolean / enum 加算・減算 同じ型同士の計算 同じ型 乗算 同じ型同士の乗算は意味がないことが多い 別の数値型 除算 同じ型の除算と、異なる型の除算では、意味が異なる 別の数値型 境界 Max, Min の定義 同じ型(の固定値) 列挙の操作 previous(), next() が可能な集合 (循環が可/不可) 同じ型 文字列表現 値の標準的な文字列表現 toString() 文字列型 文字列からの生成 標準的な文字列表現からのオブジェクト生成 parse() 同じ型 単一値の計算・判定ロジック 2019/5/11 36
  37. 37. 計算の種類 説明、メソッド例 結果の型 等値判定 isEqual( other ) , notEqual( other ) boolean / enum 大小判定 greaterThan( other ), lessThan( other ), … boolean / enum 範囲に含まれる contains( element ), encloses( other ) boolean / enum 範囲が重複する isOverlapped(other) boolean / enum 厳密に隣接する isConnectedTo(other) boolean / enum 境界の値 Max, Min 要素の型 範囲演算 intersect(other), minus(other), add(other) 範囲型 文字列表現 標準的な文字列表現 toString(), show(), describe() 文字列型 範囲型(from-to)の計算・判定ロジック 2019/5/11 37
  38. 38. 値オブジェクト(独自の型)の効果 2019/8/31 38 ➢独自の型はロジックを集約する • 型名=ルール名 • 金額型=金額の計算ルール、金額の判断ルールの置き場所 • ロジックが一か所に集まる(コードの重複を防ぐ) ➢独自の型は可読性を向上する • コードの曖昧性が減る → コードの意図が理解しやすい • プリミティブな型は汎用。独自の型は用途限定。 • 整数演算をしたいのではなく、金額計算をしたい。
  39. 39. 値オブジェクト(独自の型)の効果 2019/8/31 39 ➢独自の型は信頼性を向上する (契約による設計) • 引数の型 → 必ず有効な値を渡す約束 • メソッドが返す型 → 必ず有効な値を返す約束 • 冗長な検査ロジックが不要になる(例えば null チェック) ➢独自の型はコードの追跡を容易かつ確実にする • 型を使っている個所 = そのビジネスルールに関係する個所 • 型による追跡性 vs 変数名による追跡性 • アプリケーション全体で、ビジネスの関心事との対応がとれたコードが増 える
  40. 40. 条件分岐を型で表現する 2019/8/31 40
  41. 41. 条件分岐との戦い 2019/8/31 41 顧客区分、商品種別、有効期間、地域区分、金額区分、数量区分、 取引種類、取引状態、支払い方法、支払いタイミング、 割り増し条件、割引条件、キャンセル可能条件、… if文、boolean で表現された 暗黙的な区分 レガシーで 怪しげなコード体系 未使用と思われるコード 複数の分類軸の混在したコードマスター 通常の区分と超レアケースの混在 … 区分名が登場しない条件判断式 true/false に隠蔽された区分
  42. 42. 区分の明示化とリファクタリング 2019/8/31 42 if文やboolean で 表現された暗黙の区分 レガシーで 怪しげなコード体系
  43. 43. 区分の明示化とリファクタリング 2019/8/31 43 型を使った 列挙 たとえば Java enum if文やboolean で 表現された暗黙の区分 レガシーで 怪しげなコード体系
  44. 44. 区分の明示化とリファクタリング 2019/8/31 44 型を使った 列挙 enumに区分ごとの 計算・判定ロジックを寄せる たとえば Java enum コードがぎこちなくなったら 区分体系のリファクタリング if文やboolean で 表現された暗黙の区分 レガシーで 怪しげなコード体系
  45. 45. 区分の明示化とリファクタリング 2019/8/31 45 型を使った 列挙 区分体系のリファクタリング enumに区分ごとの 計算・判定ロジックを寄せる たとえば Java enum 区分名の変更 分類軸の分割 例外的区分の除去 区分が整理できたら、計算・判定ロジックを寄せる コードがぎこちなくなったら 区分体系のリファクタリング if文やboolean で 表現された暗黙の区分 レガシーで 怪しげなコード体系
  46. 46. 区分の明示化とリファクタリング 2019/8/31 46 型を使った 列挙 区分体系のリファクタリング enumに区分ごとの 計算・判定ロジックを寄せる たとえば Java enum 区分名の変更 分類軸の分割 例外的区分の除去 区分が整理できたら、計算・判定ロジックを寄せる コードがぎこちなくなったら 区分体系のリファクタリング if文やboolean で 表現された暗黙の区分 レガシーで 怪しげなコード体系 改善を繰り返す
  47. 47. 条件分岐を型安全にする効果 2019/8/31 47 ➢列挙型(区分値)にロジックが集まる ➢列挙型(区分名)が可読性を向上する ➢列挙型による信頼性の向上(契約による設計) ➢列挙型はコードの追跡を容易かつ確実にする
  48. 48. ビジネスルールをコレクションで表現する 2019/8/31 48
  49. 49. ビジネスルールの記述にコレクションを使う 2019/8/31 49 Mapを使った料金ルールの早見表 Setを使ったスキルセットのマッチングロジック Listを使った集計、最適要素の発見 ロジックを集約した型のコレクション コレクションのコレクション
  50. 50. 操作の種類 説明、メソッド例 結果の型 サイズ count() int 要素の検査 contains(要素), isEmpty(), notEmpty() boolean / enum 部分集合 select(条件), reject(条件), コレクション 集約演算 sum(), min(), max(), average(), … 集約結果の型 集合演算 insersect(other), minus(other), add(other) コレクション 変換 unique(), sort(), groupBy() コレクション 要素の取り出し first(), last(), at(index) 要素の型 要素の追加 add(), addAll(), append(), insertAt(), … void 文字列表現 show(), describe() 文字列, 文字列[ ] コレクション操作のカプセル化 2019/5/11 50
  51. 51. コレクションをカプセル化する効果 2019/8/31 51 ➢コレクションを内部に持った独自の型にコレク ション操作ロジックが集まる ➢型名が可読性を向上する ➢型による信頼性の向上(契約による設計) ➢独自のコレクション型はコードの追跡を容易か つ確実にする
  52. 52. ビジネスルールを独自の型で表現する 2019/8/31 52
  53. 53. 独自の型を使う効果 2019/8/31 53 ➢独自の型にビジネスロジックが集まる ➢型名が可読性を向上する ➢型による信頼性の向上(契約による設計) ➢型はコードの追跡を容易かつ確実にする
  54. 54. ビジネスルールを独自の型で表現する 役立つ技法の学び方 2019/8/31 54
  55. 55. エヴァンス本の拾い読みのススメ 2019/8/31 55 1章 継続的な学習、知識豊富な設計、深いモデル 2章 声に出してモデリングする、説明のためのモデル 9章 概念を掘り出す、それほど明示的でない概念をモデル化する方法 10章 閉じた操作、副作用のない関数、設計の宣言的スタイル 15章 コアドメイン、蒸留の拡大、強調されたコア、隔離されたコア 16章 責務のレイヤ 17章 大規模な構造と蒸留を組み合わせる 全体:クラス図にメソッド定義 or 制約の記述がある個所 ビジネスロジックに焦点を合わせ、独自の型を定義するための必読個所
  56. 56. ビジネスルールを型で表現した サンプルコードが豊富 2019/8/31 56
  57. 57. 開発現場での実験結果と考察 2019/8/31 57
  58. 58. ドメイン駆動設計の設計スタイル 2019/8/31 58 ビジネスルールに基づく計算と判断のロジック に焦点を合わせる ビジネスルールに登場する値の種類に注目して 独自の型を定義してロジックを整理する ビジネスルールを記述する部分の設計と実装が アプリケーション全体の構造と秩序を左右する
  59. 59. 現場で確認できたこと 2019/8/31 59 コードを考えて書く人 コードを書かない人
  60. 60. 現場で確認できたこと 2019/8/31 60 コードを考えて書く人 コードで具体的に話せるので、意図ややり方は確実に伝わる サンプルコード、可視化ツール、ガイドラインもだいぶ整った 入出力に焦点をあわせる設計スタイルからの転換パターンは個人差 体にどのくらいしみついているか? どのくらい発想が柔軟か? コードを書かない人
  61. 61. 現場で確認できたこと 2019/8/31 61 コードを考えて書く人 コードで具体的に話せるので、意図ややり方は確実に伝わる サンプルコード、可視化ツール、ガイドラインもだいぶ整った 入出力に焦点をあわせる設計スタイルからの転換パターンは個人差 体にどのくらいしみついているか? どのくらい発想が柔軟か? コードを書かない人 ドメイン駆動設計の設計スタイルを言葉で伝えるのは無理 時間のむだかも 設計やその影響に関心を持っているの関係者の一部だけ 「ドメイン駆動設計」をユビキタス言語にしない コードを書かない人の関心の文脈で、見せるようにする 可視化ツールは、そういう発想から生まれた
  62. 62. コードで確認できる発想の変化 独自の型の量と質 パッケージの構造、パッケージ名 入出力の記述個所への独自の型の浸透 2019/8/31 62
  63. 63. 言葉と会話で確認できる発想の変化 タスク名、ToDo名、コミットログ 質問やアドバイスに登場する言葉 パッケージ名、クラス名、メソッド名の相談 ロジックの置き場所の相談 2019/8/31 63

×