Publicité
Publicité

Contenu connexe

Présentations pour vous(20)

Similaire à ドメイン駆動設計 本格入門(20)

Publicité

Plus de 増田 亨(20)

Dernier(20)

Publicité

ドメイン駆動設計 本格入門

  1. ドメイン駆動設計 本格入門 有限会社 システム設計 増田 亨 PREMIUM #3 2019.3.22
  2. はじめる前に • ブログを書くかもしれないという方へ 2019/3/22 ©有限会社 システム設計 2
  3. 全体の流れ 2019/3/22 ©有限会社 システム設計 3 ドメイン駆動設計の考え方 ドメイン駆動設計を理解する三つのキーワード エヴァンス本のススメ レガシーに立ち向かう マイクロサービスとドメイン駆動設計
  4. ドメイン駆動設計の考え方 ©有限会社 システム設計 42019/3/22
  5. 2019/3/22 ©有限会社 システム設計 5 ドメイン駆動設計でなぜつくるのか 「ソフトウエアの核心にある複雑さに立ち向かう」 とはどういうことか?
  6. ドメイン駆動設計でなぜつくるのか ©有限会社 システム設計 62019/3/22
  7. ソフトウェアの変更を楽で安全にするため ➢ 何年ものあいだ、成長と進化を続けるソフトウエア ➢ 新たな要求に対し柔軟性と拡張性をもってこたえるソフトウェア ➢ しなやかに設計された変更が容易なコードベース ➢ 豊富な機能を持った大きなシステムの段階的な成長 出典: まえがき 対照的な3つのプロジェクト エピローグ 5つのプロジェクトのその後 2019/3/22 ©有限会社 システム設計 7
  8. すべてにプラスに作用する 2019/3/22 ©有限会社 システム設計 8 変更が楽で安全 ビジネスの要求 開発スピード 開発コスト 運用コスト 性能改善 セキュリティ向上 使いやすさ
  9. すべてにマイナスに作用する 2019/3/22 ©有限会社 システム設計 9 変更がやっかいで危険 ビジネスの要求 開発スピード 開発コスト 運用コスト 性能改善 セキュリティ向上 使いやすさ
  10. ドメイン駆動設計のやり方 ©有限会社 システム設計 102019/3/22
  11. 変更を楽で安全にするための 2019/3/22 ©有限会社 システム設計 11 関心の分離の工夫 モジュール構造の工夫
  12. ソフトウェアの核心にある複雑さに立ち向かう ©有限会社 システム設計 122019/3/22
  13. ドメイン駆動設計を理解する 三つのキーワード ©有限会社 システム設計 132019/3/22
  14. 2019/3/22 ©有限会社 システム設計 14 ドメインロジック 複雑さの根源 ドメインモデル 複雑さをモデルで整理 オブジェクト指向 モデルと実装の一致
  15. 要点を絞り込む ©有限会社 システム設計 152019/3/22
  16. 2019/3/22 ©有限会社 システム設計 16 ドメインロジック → ビジネスルール ドメインモデル → 計算モデル オブジェクト指向 → 型指向のプログラミング
  17. ビジネスルール ©有限会社 システム設計 172019/3/22
  18. ソフトウエアが複雑になる理由 ビジネスルール 金額、数量、期日、場所などの計算と判定 ビジネスルールを適用する条件による分岐 顧客区分、商品種別、有効期間、地域区分、金額区分、数量区分、 取引種類、取引状態、支払い方法、支払いタイミング、 割り増し条件、割引条件、キャンセル可能条件、… 2019/3/22 ©有限会社 システム設計 18
  19. 複雑さと戦う準備 ©有限会社 システム設計 192019/3/22
  20. ビジネスルールの記述を 独立したモジュールに分離する 2019/3/22 ©有限会社 システム設計 20
  21. ビジネスルールの記述を独立させる プレゼンテーション層の モジュール群 アプリケーション層の モジュール群 データソース層の モジュール群 ビジネスルールを 記述したモジュール群 利用する 2019/3/22 ©有限会社 システム設計 21
  22. ビジネスルールの記述を独立させる効果 プレゼンテーション層のモジュール群がシンプルになる アプリケーション層のモジュール群がシンプルになる データソース層のモジュール群がシンプルになる 三つの層から区分判定などの条件分岐が激減する 三つの層のモジュール群の設計がパターン化し安定する 2019/3/22 ©有限会社 システム設計 22
  23. ビジネスルールを記述するモジュール群に 複雑さが集中する 複雑なビジネスルールを整理し わかりやすく記述するための考え方とやり方 2019/3/22 ©有限会社 システム設計 23
  24. 従来のモジュール構造とビジネスルール トランザクションスクリプト 機能(データ処理手続き)に分割したモジュール群 ビジネスルールの記述、特に条件判定が、 あちこちのモジュールに分散し、かつ、重複する 変更がやっかいで危険 2019/3/22 ©有限会社 システム設計 24
  25. ビジネスルールの複雑さにどう立ち向かうか ©有限会社 システム設計 252019/3/22
  26. 計算モデル ©有限会社 システム設計 262019/3/22
  27. モデル • 複雑さに立ち向かうときの根底技法 • 全体をシンプルにとらえて説明する試み • 関心の分離 • 「抽象」というよりは「分離」 • 枝葉末節も、最終的には必要になるので安易に切り捨てない • 要点を特定することと、要点以外を無視することを混同しない • 焦点を合わせるが、周辺も見る (いったりきたりする) • (計算の)中核と周辺 • (計算の)主軸と補助軸 2019/3/22 ©有限会社 システム設計 27
  28. 計算モデル 計算モデル • 計算式 • 判定式 • 判定結果による条件分岐 データモデル • 計算(プログラム)の関心事から独立したデータの記録と参照のモデル • ビジネスアプリケーションを実現するために必須 • しかし、ソフトウェアの複雑さに立ち向かう主軸ではない 2019/3/22 ©有限会社 システム設計 28
  29. ビジネスルール → 計算モデル ©有限会社 システム設計 292019/3/22
  30. ビジネスルールのモデリング Fact 事実の表現 ビジネスの状況の記録や通知に使う値の種類 ・ 数値、日付、場所、識別番号、名称、… Rule Factを使った 計算や判定のロジック 計算式 同一性の判定式 大小の比較式 Goal 知りたいこと 計算結果や判定結果を表現する値の種類 ・合計金額、予定日、残数、… ・出荷可否、受付可否、割引種類、… 2019/3/22 ©有限会社 システム設計 30
  31. ビジネスルールのモデリング • データモデル → 外周の関心事 • 計算に必要な元データの記録と参照 • 計算結果の記録 • 計算モデル → 中核の関心事 • ビジネスルールの計算ロジック判定ロジックそのもの • メモリ上で完結する • 計算と入出力の分離 • 計算の準備としての入力 • 計算の後処理として出力 2019/3/22 ©有限会社 システム設計 31
  32. ビジネスルールの記述が中核の関心事 プレゼンテーション層の モジュール群 アプリケーション層の モジュール群 データソース層の モジュール群 ビジネスルールを 記述したモジュール群 利用する 2019/3/22 ©有限会社 システム設計 32
  33. 計算モデルをどう整理して記述するか ©有限会社 システム設計 332019/3/22
  34. 型指向のプログラミング ©有限会社 システム設計 342019/3/22
  35. 型指向のプログラミング ビジネスルール(計算/判定)の記述をモジュール化する基本 値の種類(=型)ごとにクラス(モジュール)定義する 例:数値を扱う BigDecimal型, 日付を扱う LocalDate型 ただし、個々のビジネスルールを記述するには汎用的すぎる 2019/3/22 ©有限会社 システム設計 35
  36. 型指向のプログラミング ビジネスルールに登場する値を分類する 値の種類(=型)ごとに、独自のクラスを定義する 値の種類ごとに有効な値の範囲を定義する 値の種類ごとに必要な計算・判定のロジックを記述する 2019/3/22 ©有限会社 システム設計 36
  37. ビジネスルールを 型指向のプログラミングで記述する 2019/3/22 ©有限会社 システム設計 37
  38. ビジネスルールを記述する3要素 Fact 事実の表現 ビジネスの状況の記録や通知に使う型 ・ 数値、日付、場所、識別番号、名称、… Rule Factを使った 計算や判定のロジック 計算式 同一性の判定式 大小の比較式 Goal 知りたいこと 計算結果や判定結果を表現する型 ・合計金額、予定日、残数、… ・出荷可否、受付可否、割引種類、… 2019/3/22 ©有限会社 システム設計 38
  39. Fact-Rule-Goalで記述する 3つの設計パターン 値オブジェクト ロジックを持ったenum コレクションのカプセル化 2019/3/22 ©有限会社 システム設計 39
  40. 値オブジェクト 2019/3/22 ©有限会社 システム設計 40
  41. 値オブジェクトとは? • Fact の表現手段 • 数値、時間、場所、識別番号、識別名称、… • ビジネスとして適切な値の範囲を定義する • Rule (計算ロジックや判定ロジック)の置き場所 • Factを使う計算や判定をメソッドとして記述する • Factと持つオブジェクトに、関連するロジックを集める • Goal 知りたいこと(計算結果、判定結果)の表現手段 • 知りたいことを表現した型(値の種類)を設計する • メソッドの返す型として使う 2019/3/22 ©有限会社 システム設計 41
  42. 値オブジェクトのカタログ 単一の値 範囲型(from-to) 範囲型のコレクション 数 値 金額型 Amount, Money 金額範囲 x円以上 y円未満 金額範囲のコレクション 価格帯 数量型 Quantity, NumberOfXxx 数量範囲 m人以上 n人以下 数量範囲のコレクション 数量別割引率 時 間 日付型 DueDate, XxxDate 期間 開始日 - 終了日 期間のコレクション シーズン 時刻型 HourTime, XxxTime 時間 開始時刻 – 終了時刻 時間のコレクション 時間帯 空 間 地点型 Point 接続 Path:出発点 – 到達点 接続のコレクション Route [Path,…] - 地域型 Area, Zone 地域のコレクション 階層、隣接関係、… 2019/3/22 ©有限会社 システム設計 42
  43. 値オブジェクトの効果 • 値オブジェクト=ビジネスに特化した値の種類を明示的に表現 • 動かすだけなら、プログラミング言語が提供する汎用的な型だけでよい • プログラムの表現が、ビジネスルールの記述そのものになる • 値の種類単位で、ビジネスロジックの記述が一か所にまとまる • プログラムのあちこちにビジネスルールの記述が重複しない • ビジネスルールが変わったときのソフトウェアの変更が楽で安全 2019/3/22 ©有限会社 システム設計 43
  44. 値オブジェクトを設計する 計算の意図を、メソッド名とメソッドの返す型で説明する 2019/3/22 ©有限会社 システム設計 44
  45. 計算の種類 説明、メソッド例 結果の型 等値判定 isEqual( other ) , notEqual( other ) boolean / enum 大小判定 greaterThan( other ), lessThan( other ), … boolean / enum 加算・減算 同じ型同士の計算 同じ型 乗算 同じ型同士の乗算は意味がないことが多い 別の数値型 除算 同じ型の除算と、異なる型の除算では、意味が異なる 別の数値型 境界 Max, Min の存在 同じ型(の固定値) 列挙 prev(), next() が可能な集合 (循環が可/不可) 同じ型 文字列表現 値の標準的な文字列表現 toString() 文字列 文字列からの生成 標準的な文字列表現からのオブジェクト生成 parse() 同じ型 計算の候補(単一値) 2019/3/22 ©有限会社 システム設計 45
  46. 計算の種類 説明、メソッド例 結果の型 等値判定 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/3/22 ©有限会社 システム設計 46
  47. 計算の種類(メソッド)の設計原則 • ある値について、ビジネスルールに必要な計算は、限定的 • 金額と金額の足し算はある • 金額と金額の掛け算はない • ビジネスルールの値の範囲は、限定的 • 境界値がある • 1以上99まで • 現在日以降 90日以内 • 計算の意図を、メソッド名、メソッドの渡す引数の型、メソッドの返す 型で説明する 2019/3/22 ©有限会社 システム設計 47
  48. 値オブジェクトを使って変更を安全にする 契約による設計 2019/3/22 ©有限会社 システム設計 48
  49. 契約による設計 変更を楽で安全にするための設計技法 assert による表明 型による表明 防御的な検査コードを書かない 事前条件(クラスを使う側の責任:引数の型) 事後条件(計算を提供するクラスの責任:返り値の型) 暗黙のビジネスルールの明文化につながる 値の範囲と計算の種類を限定 → 動作が安定する 2019/3/22 ©有限会社 システム設計 49
  50. enumを使った区分ごとのロジックの整理 2019/3/22 ©有限会社 システム設計 50
  51. 区分ごとのビジネスルールを扱う 区分ごとの条件分岐が複雑さの大きな原因 enumは区分ごとのロジックを整理する強力な手段 enumを使うと区分体系の問題の発見と改善が進む 2019/3/22 ©有限会社 システム設計 51
  52. 区分を列挙しただけのenumを作る 区分ごとの定数をenumのフィールド変数に移動 区分ごとの計算や判定のロジックをenumのメソッドに移動 コードがゆがむ(フィールド変数やメソッドの一貫性が崩れる) 区分のリファクタリング(区分の分解、再定義) ビジネスルール記述のわかりやすさにブレークスルーが起きる 2019/3/22 ©有限会社 システム設計 52
  53. コレクションのカプセル化 2019/3/22 ©有限会社 システム設計 53
  54. コレクション操作の問題と改善 問題 あちこちにコレクションを操作する類似の記述が分散 バグが紛れ込みやすい(計算の不整合が起きやすい) コレクション操作の手続きは、ビジネスの関心事ではない 改善策 目的別のコレクション型を独自につくる コレクション操作のロジックをそのクラスに集める コレクション操作の詳細を隠蔽する 2019/3/22 ©有限会社 システム設計 54
  55. コレクションのカプセル化の効果 コレクション操作がちらばっていたコードのぐちゃぐちゃ感が消える コレクションに必要な計算を集めると、リファクタリングがやりやすい コレクション操作の整合性と一貫性が向上する コレクション操作という技術手段が隠蔽され クラス名、メソッド名、メソッドの返す型で ビジネスの関心事が前面に登場する 2019/3/22 ©有限会社 システム設計 55
  56. 計算の種類 説明、メソッド例 結果の型 サイズ 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/3/22 ©有限会社 システム設計 56
  57. ドメイン駆動設計を理解する 三つのキーワード ©有限会社 システム設計 572019/3/22
  58. 2019/3/22 ©有限会社 システム設計 58 ドメインロジック → ビジネスルール ドメインモデル → 計算モデル オブジェクト指向 → 型指向のプログラミング
  59. エヴァンス本のススメ 2019/3/22 ©有限会社 システム設計 59
  60. エリック・エヴァンスの ドメイン駆動設計 2019/3/22 ©有限会社 システム設計 60
  61. 登場するパターン 2019/3/22 ©有限会社 システム設計 61 基本要素 エンティティ 値オブジェクト ドメインサービス モジュール オブジェクトの ライフサイクル 集約(アグリゲート) リポジトリ ファクトリ ユビキタス言語 モデル駆動設計 実践的モデラー しなやかな設計 意図の明白なインタフェース 副作用のない関数 表明 概念の輪郭 独立したクラス 閉じた操作 レイヤードアーキテクチャ スマートUI コンテキスト境界 継続的な統合 コンテキストマップ 共有カーネル 顧客・供給者 順応者 腐敗防止層 別々の道 公開ホストサービス 公表された言語 コアドメイン 汎用的なサブドメイン 凝集されたメカニズム ドメインビジョン声明文 コアのハイライト コアの隔離 コアの抽象化 進化する秩序 システムのメタファ 責務のレイヤ 知識レベル・運用レベル
  62. パターンについて • ひとつひとつのパターンだけ取り上げて理解しても役に立たない • よく登場するパターン名がドメイン駆動設計の本質ではない • パターンの背景にある動機を理解する • パターンとパターンの関係を理解する • そのためには、パターンの拾い読みではなく、本の構成と全体の流 れを理解したほうが良い 2019/3/22 ©有限会社 システム設計 62
  63. よく登場するパターンへの注釈 エンティティ ビジネスルールや計算モデルとして主要な関心事ではない どちらかといえば入出力(記録と参照)の関心事 値オブジェクト ビジネスルールの整理と実装の主役 計算モデルの構成要素として、別格の重要度 ドメインサービス 型指向のプログラミングの道具ではない メソッドの引数をインスタンス変数に持つオブジェクトの設計を試みる 集約(アグリゲート) 計算ロジックの集約 データの集約ではない 維持するのは、データベースの整合性ではなく、計算の整合性と一貫性 リポジトリ 計算の準備と計算結果の記録の仕組み 入出力の関心事であり、計算モデルの一部ではない 2019/3/22 ©有限会社 システム設計 63
  64. よく登場するパターンへの注釈 ユビキタス言語 目的ではない 共通言語 どこにでも、いつでも登場する言葉 ビジネスをどこまで理解し、意識してコードを書いているかの評価軸 コードや技術者同士の会話で、どこでも、いつでも登場しているか? 境界づけられたコンテキスト 目的ではない コミュニケーションや共通理解の現状を把握する手段 一つのチームに複数のコンテキストが存在するリスクへの警鐘 (継続的な統合:CI) ビルドとテストの自動化が本質ではない(ビルドOK,テストOKでは不十分) チーム内で、ビジネスルール理解と計算モデル表現を整合させる そのためには頻繁な会話が必要(特にちょっとした違和感の確認) コンテキストマップ 計算モデルのマッピング データ入出力のマッピングではない 同じ計算モデルの通用範囲 値の種類の名前が登場するかしないか 同じ名前の値の種類は、内容が同じか(値の範囲、計算の種類) 2019/3/22 ©有限会社 システム設計 64
  65. エヴァンス本の要点を確認する ©有限会社 システム設計 652019/3/22
  66. ドメイン駆動設計でなぜつくるのか ©有限会社 システム設計 662019/3/22
  67. ソフトウェアの変更を楽で安全にするため ➢ 何年ものあいだ、成長と進化を続けるソフトウエア ➢ 新たな要求に対し柔軟性と拡張性をもってこたえるソフトウェア ➢ しなやかに設計された変更が容易なコードベース ➢ 豊富な機能を持った大きなシステムの段階的な成長 出典: まえがき 対照的な3つのプロジェクト エピローグ 5つのプロジェクトのその後 2019/3/22 ©有限会社 システム設計 67
  68. 2019/3/22 ©有限会社 システム設計 68 ドメインロジック 複雑さの根源 ドメインモデル 複雑さをモデルで整理 オブジェクト指向 モデルと実装の一致
  69. 要点を絞り込んで理解する ©有限会社 システム設計 692019/3/22
  70. 2019/3/22 ©有限会社 システム設計 70 ドメインロジック → ビジネスルール ドメインモデル → 計算モデル オブジェクト指向 → 型指向のプログラミング このように意味を限定して読んでみると、ずいぶんわかりやすくなる
  71. エヴァンス本の全体構成を理解する ©有限会社 システム設計 712019/3/22
  72. 全体の構成 2019/3/22 ©有限会社 システム設計 72 第1部 ドメインモデルを 機能させる 第2部 モデル駆動設計の 構成要素 第3部 深い洞察に向かう リファクタリング 第4部 戦略的設計 1章~3章 4章~7章 8章~13章 14章~17章 概論と基本事項 ここだけでは役に立たない 役に立つモデルを 手に入れるための 実用的な設計技法 大規模に適用する 長期的に取り組む ための技法
  73. エヴァンス本の中核 ©有限会社 システム設計 732019/3/22
  74. 第3部:役に立つモデルの実用的な設計技法 2019/3/22 ©有限会社 システム設計 74 9章 暗黙的な概念を明示的にする 10章 しなやかな設計 ビジネスルールが コードで明示できてないことの検知 「制約」や「ルール」を クラスやメソッドで表現する実験 ぎこちなくても、とにかくコードにしてみる 明示的になった素材を改善する設計技法 意図の明白なインタフェース 副作用のない関数 表明 概念の輪郭 独立したクラス 閉じた操作 表現を 改善する ビジネスを 理解する
  75. 第4部:大規模に長期的に取り組む 2019/3/22 ©有限会社 システム設計 75 14章 モデルの整合性を維持する 15章 蒸留 16章 大規模な構造 大規模・長期的に 取り組むための準備 境界づけられたコンテキスト 継続的な統合 コンテキストマップ ビジネスルールの複雑さの整理と モジュール構造の改善 コアドメイン 汎用的なサブドメイン 凝集されたメカニズム ドメインビジョン声明文 コアのハイライト コアの隔離 コアの抽象化 全体の関係を共通理解にする モデル間の関係の整理と改善 責務のレイヤ (能力・運用・約束・ポリシー) 知識レベルと運用レベル
  76. 複雑なビジネスルールに立ち向かう技法 ©有限会社 システム設計 762019/3/22
  77. ビジネスルールの分析設計 従来のアプローチ 2019/3/22 ©有限会社 システム設計 77
  78. 従来のアプローチ • プロセスモデリング • 機能分割 • トランザクションスクリプト • データモデリング • ERモデリング • CRUD分析 • データベースアクセスのスクリプティング • ビジネスルールの発見と整理が、主軸ではない • その結果、ビジネスルールがあちこちにちらばり重複する 2019/3/22 ©有限会社 システム設計 78
  79. ビジネスルールの分析設計 ドメイン駆動設計のアプローチ 2019/3/22 ©有限会社 システム設計 79
  80. 2019/3/22 ©有限会社 システム設計 80 ドメインロジック → ビジネスルール ドメインモデル → 計算モデル オブジェクト指向 → 型指向のプログラミング
  81. ビジネスルールを記述する3要素 Fact 事実の表現 ビジネスの状況の記録や通知に使う型 ・ 数値、日付、場所、識別番号、名称、… Rule Factを使った 計算や判定のロジック 計算式 同一性の判定式 大小の比較式 Goal 知りたいこと 計算結果や判定結果を表現する型 2019/3/22 ©有限会社 システム設計 81
  82. Fact-Rule-Goalで記述する 3つの基本パターン 値オブジェクト ロジックを持ったenum コレクションのカプセル化 2019/3/22 ©有限会社 システム設計 82
  83. ビジネスルールの発見と整理の枠組み 2019/3/22 ©有限会社 システム設計 83
  84. 責務のレイヤ (能力・運用・約束・ポリシー) 2019/3/22 ©有限会社 システム設計 84
  85. 責務のレイヤの例 ポリシー 事業運営の決め事 価格、割引、優遇、拒絶 オーバーブッキング キャンセル 約束 顧客との契約 取引先との契約 見積 予約 注文 運用 ビジネス活動の実態(イベント) 出荷、売り上げ 請求、回収 能力 ビジネスの現実(リソース) 在庫 出荷能力 処理能力 2019/3/22 ©有限会社 システム設計 85
  86. ビジネスルールの3つの源泉 価値提供の約束と支払いの約束 ビジネス活動の連鎖/約束の連鎖 競争優位の獲得策/競争劣位の防止策 契約 バリュー チェーン 事業運営 ポリシー 2019/3/22 ©有限会社 システム設計 86
  87. 約束 何を(区分) どのくらい(数量) いつ(日時) いくらで(金額) 誰に(区分) 2019/3/22 ©有限会社 システム設計 87
  88. 能力:約束してよいこと/約束できないこと 出荷可能な在庫 配送能力 キャパシティ(空席、空きスペース、…) アベイラビリティ(人、空間、モノ、…) 2019/3/22 ©有限会社 システム設計 88
  89. 運用:約束の履行の監視と促進の決め事 いつ何が起きるべきか(イベント区分、状態区分) 起きたことの検知 起きなかったことの検知 起きた場合のアクション 起きなかった場合のアクション 2019/3/22 ©有限会社 システム設計 89
  90. ポリシー • 価格、割引 • 特典、優遇 • 提供ポリシー(時間、場所、相手、許容量、…) • オーバーブッキング • 与信 • キャンセル 2019/3/22 ©有限会社 システム設計 90
  91. 約束違反の扱いの決め事 約束のキャンセル(可否の判断、可能な場合の補償) 価値を提供できなかった時のルール(返品、返金、…) 対価の支払いができなかった時のルール(ペナルティ、…) 2019/3/22 ©有限会社 システム設計 91
  92. エヴァンス本の構成 2019/3/22 ©有限会社 システム設計 92 第1部 ドメインモデルを 機能させる 第2部 モデル駆動設計の 構成要素 第3部 深い洞察に向かう リファクタリング 第4部 戦略的設計 1章~3章 4章~7章 8章~13章 14章~17章 概論と基本事項 ここだけでは役に立たない 役に立つモデルを 手に入れるための 実用的な設計技法 大規模に適用する 長期的に取り組む ための技法
  93. ドメイン駆動設計の考え方で レガシーに立ち向かう 2019/3/22 ©有限会社 システム設計 93
  94. 2019/3/22 ©有限会社 システム設計 94 ドメインロジック → ビジネスルール ドメインモデル → 計算モデル オブジェクト指向 → 型指向のプログラミング
  95. ビジネスルールを記述する3要素 Fact 事実の表現 ビジネスの状況の記録や通知に使う型 ・ 数値、日付、場所、識別番号、名称、… Rule Factを使った 計算や判定のロジック 計算式 同一性の判定式 大小の比較式 Goal 知りたいこと 計算結果や判定結果を表現する型 2019/3/22 ©有限会社 システム設計 95
  96. ビジネスルールの3つの源泉 価値提供の約束と支払いの約束 ビジネス活動の連鎖/約束の連鎖 競争優位の獲得策/競争劣位の防止策 契約 バリュー チェーン 事業運営 ポリシー 2019/3/22 ©有限会社 システム設計 96
  97. レガシーへの立ち向かい方:心の準備 • ありがちな設計 • トランザクションスクリプト(機能単位のモジュール) • バッチ処理 • テーブルは更新可能なデータファイル • ありがちな状況 • 設計や分析の資料はない/あっても古くてコードと一致していない • 命名規約は、番号重視 and/or 省略重視 ( KBN01 ) • 使われていないロジック、データ、区分が混在 • 手がかり • 実際に業務が回っている(実データがある) • 画面、出力帳票、データ交換用のファイル 2019/3/22 ©有限会社 システム設計 97
  98. レガシーへの立ち向かい方:手がかり • 実データ、実画面、実帳票、実ファイル • 実際に使われているデータ(事実の記録)が最大の手がかり • プログラムの意図は、コードからは読み取りにくい • そういう設計のスタイルだから • コードは意図の表現ではなく、データ処理の手続きの実現 • 目のつけどころ • 区分値 ビジネスルールの複雑さの根源 • 導出項目 ビジネスルールの計算・判定の結果 2019/3/22 ©有限会社 システム設計 98
  99. 区分値の調査と分析 • コード内のif文やswitch文と格闘する前に、区分体系を徹底的に調 査する • データベースの区分カラム • GROUP BY 句で、実際のデータ内容の確認 • 区分によって、使うカラム/使わないカラム、意味の異なるカラムの特定 • 画面の区分表示、区分選択ボックス • データベースの区分カラムとの対応 • 業務的な使い方の確認 2019/3/22 ©有限会社 システム設計 99
  100. 導出項目の調査と分析 • 導出項目の特定 • ビジネスルールを適用した計算結果 • 金額、数量、期日、場所、区分 • 画面の表示項目 • データベースに記録された導出結果 • 導出ルールの調査 • 業務マニュアル/利用ガイド/料金表 … • ソースコード • ヒアリング(ありえないデータ、ありえない結果を判断できる能力を持つ人) 2019/3/22 ©有限会社 システム設計 100
  101. あるべき姿の中核を見極める • 導出(計算・判定)に焦点を合わせる • 単なる記録と参照は、いったんスコープ外にする • データベースは、計算・判定で使う項目に焦点を合わせる • 画面項目も、計算・判定で使う項目/導出結果に焦点を合わせる • ソースコード中の、計算式と判定式に焦点を合わせる • 単なるデータの記録と参照は、ばっさりスコープからはずす 2019/3/22 ©有限会社 システム設計 101
  102. あるべき姿の中核を生み出す • データベース • 導出の元になるデータと、導出結果だけに絞り込んだデータベースを用意する • FACTを正しく記録するためのテーブル群を新規に設計 • イミュータブルデータモデル • データベース制約を徹底する • 特に NOT NULL 制約 • 現行のデータベースから必要データを複製する仕組みづくり • 導出ロジックのプログラミングと検証 • FACT駆動で作成した新データベースから、必要な計算・判定ができるプログラムを 開発する • 計算結果・判定結果を、既存データベースの該当カラムと突き合わせる 2019/3/22 ©有限会社 システム設計 102
  103. 複雑さの核心に切り込む • 既存の区分体系 • 未使用の区分 • 今となっては意図が不明な区分 • 複数の区分軸の混在 • 区分体系の整理 • 未使用を使わない • 意図不明もいったん使わない • 明らかな例外を、事前処理で除外する • 残った区分を論理的に分解する • 2軸か3軸の組み合わせになっていることが多い • すべての組み合わせが網羅されていないことが多い(その理由を分析する) 2019/3/22 ©有限会社 システム設計 103
  104. アプリケーションとして組み立てる • 中核は手に入った • FACTを記録したテーブル群(と実データ) • FACTを使った導出プログラム(計算モデル) • 計算サービス、判定サービス • 中核を使って • 画面や外部インタフェース • 作り直す • 既存の画面処理プログラムや、外部インタフェースプログラムから呼び出す • 記録して参照するだけのデータ群 • 中核の外周に追加する • 既存の処理にまかせる 2019/3/22 ©有限会社 システム設計 104
  105. マイクロサービスとドメイン駆動設計 ©有限会社 システム設計 1052019/3/22
  106. マイクロサービスアーキテクチャ ひとつのアプリケーションを複数のサービスで構築する 開発の独立性 • サービスごとに開発活動が独立 • サービスごとに修正・拡張が独立 • サービスごとに設計改善が独立 配置と運用の独立性 • サービスごとに運用が独立 • ただし、高可用性が要求される • サービス単位での自動スケーリング 2019/3/22 ©有限会社 システム設計 106
  107. マイクロサービスへの分割 4つの軸 ©有限会社 システム設計 1072019/3/22
  108. 2019/3/22 ©有限会社 システム設計 108 分割の軸 説明 予想される アンチパターン ビジネス能力 ビジネスアーキテクチャに合わせる 部門・業務・職務 (3段階の機能分割) 大きなきれいな絵と 入り組んだ現実のシステム構造 ドメインモデル ビジネスルール単位で分割 ・価格、割引、特典、… ・在庫引き当て、予約、キャンセル、… ルールの依存性の整理の失敗 区分設計の失敗 アクション指向 アクション単位(イベント単位)に分割 引き合い、見積、在庫確認、受注、 出荷指示、売上計上、請求、… 手続き的なモジュール構造 ロジックがあちこちに重複 リソース指向 リソース単位に分割 リソース管理番号( Entity, URI ) FatなEntity/テーブル 巨大な中央データベース or データの重複と不整合
  109. 分割の方針 4つの軸の組み合わせになる 課題 • 主軸の選択 • 補助軸の組み合わせの優先順位の選択 • 大規模な取り組みの一貫性と整合性の維持 • 長期的な取り組みの一貫性と整合性の維持 • 「最初から正しい分割はできない」 • 継続的な「分割の見直し」の現実性 2019/3/22 ©有限会社 システム設計 109
  110. マイクロサービスのアーキテクチャ ドメイン駆動設計のアーキテクチャ ©有限会社 システム設計 1102019/3/22
  111. ドメイン駆動設計 • マイクロサービスへの分割を目的とはしていない • 良い設計(適切な関心の分離と変更容易なモジュール構造)を目指してい ると • シンプルなサービスの分割に進化していく • シンプルなデータベース構造に進化していく • その結果、マイクロサービス化をやりやすくなる • 配置・運用を実際にマイクロサービス化するかは、要件しだい • マイクロサービス化のトレードオフを検討する • 不必要な複雑さを持ち込まない 2019/3/22 ©有限会社 システム設計 111
  112. モノリスからマイクロサービスへの段階的移行 • ドメイン駆動設計で関心の分離とモジュール構造の改善を積重ねる • 最初はシステム全体のあちこちが変更対象になる • この段階でのマイクロサービス化は失敗への道 • ある程度、開発と設計改善が進むと • アプリケーション層のクラス/メソッドが安定する • データベース設計が安定する • この段階になってから、(必要なら)マイクロサービス化を検討する 2019/3/22 ©有限会社 システム設計 112
  113. マイクロサービス化と関係する設計技法 • アプリケーション層の分析・設計 • データベースの分析・設計 2019/3/22 ©有限会社 システム設計 113
  114. アプリケーション層の設計 2019/3/22 ©有限会社 システム設計 114 プレゼンテーション層 アプリケーション層 データソース層 データベース ビジネスルール層 使う
  115. ビジネスルールの記述を独立させる プレゼンテーション層の モジュール群 アプリケーション層の モジュール群 データソース層の モジュール群 ビジネスルールを 記述したモジュール群 利用する 2019/3/22 ©有限会社 システム設計 115
  116. アプリケーション層の複雑さ ビジネスルールの記述を、ビジネスロジック層に移動する 理論的にはアプリケーション層はとてもシンプルになる 現実はアプリケーション層に複雑なロジックが残りやすい アプリケーション層の複雑さの分析と整理 (VETRO, Saga) 2019/3/22 ©有限会社 システム設計 116
  117. VETRO分析 2019/3/22 ©有限会社 システム設計 117
  118. VETRO 分析とは? ビジネストランザクションをビジネスメッセージの処理としてとらえる メッセージ処理を5種類のアクション(VETRO)に分解してみる アクションごとに、どのルールをどのタイミングで適用するか検討する 2019/3/22 ©有限会社 システム設計 118
  119. VETRO Validation 妥当性検証 Enrich 情報付加 Translate 情報導出 Routing 分岐判定 Operation 通知/記録ビジネス メッセージ サービスを実行するステップの分解 それぞれのステップで、ビジネスルールの計算・判定をする可能性 ステップが複雑になる場合は、サービス単位を分けることを検討する 2019/3/22 ©有限会社 システム設計 119
  120. VETRO ビジネス メッセージ Event 通知、Document送付 Query 問い合わせ、Command 指示 Validation 妥当性検証 メッセージ内容の妥当性を検証する データ形式、必須属性、値範囲、… Enrich 情報付加 メッセージに含まれたIDなどから、関連する情報 を収集するルール(ex. 顧客ID->顧客購買履歴) Translate 情報導出 付加された情報を元に、新たな情報を導出する ルール (ex. 購買履歴 → 顧客ランク ) Routing 分岐判定 導出された情報を元に、適切なオペレーションに 分岐させるルール ( ex. 顧客ランクごとの対応 ) Operation 通知/記録 通知ルール:誰に何を通知すべきか? 記録ルール:どこに何を記録すべき? 2019/3/22 ©有限会社 システム設計 120
  121. Saga 複合トランザクションに分解する 2019/3/22 ©有限会社 システム設計 121
  122. Sagaとは? ③が不成立だった場合、①と②にキャンセル処理を実行する という、さまざまな状況とその対応方法(undo)の物語を用意する ①②③を、独立して、順不同で実行する (それぞれの物語) 三つともOKであれば、それで完了(Happy Goal) 独立したトランザクション A 独立したトランザクション B 独立したトランザクション C ビジネス メッセージ コーディ ネータ ひとつの大きなトランザクション → 独立した複数の小さなトランザクションに分割 2019/3/22 ©有限会社 システム設計 122
  123. Sagaとは? 独立したトランザクションのコミット • 個々のトランザクションは独立して確定する(できる) ビジネス的な undo の仕組み • どこかで不都合な状況が発生した場合、キャンセル処理など適切なカウン タートランザクションを実行する仕組みを用意する ビジネスレベルでの代替アクションの分析と実装 • 自動的なundo以外に、人間系の代替プロセスや取消プロセスの実行に引 き継ぐパターンも選択肢 • その場合の支援機能を用意する 2019/3/22 ©有限会社 システム設計 123
  124. データベース 2019/3/22 ©有限会社 システム設計 124 プレゼンテーション層 アプリケーション層 データソース層 データベース ビジネスルール層 計算モデルとデータモデルの マッピング
  125. マイクロサービスに発展可能なデータベース設計 • 事実の記録を徹底する(イベントソーシング) • テーブル単位(カラム構成)を計算の関心事に従属させる • 事実と参照を分ける(テーブル→スキーマ→データベース) • 事実と導出結果を分ける(テーブル→スキーマ→データベース) 2019/3/22 ©有限会社 システム設計 125
  126. 事実の記録:データベース設計の基本 事実の記録の原則 • NULL という事実はない • NOT NULL 制約にできないカラムは事実の記録として欠陥 • オプショナルな項目は、別テーブルにする • 発生時点の異なる事実は、別テーブルにする • 有効な値の範囲を定義する(型指向の設計) 外部キー制約には2つの意味がある • 事実の前後関係(重要) • 同じ時点の事実を別テーブルにしている関係(別事実に分解すべき可能性) 2019/3/22 ©有限会社 システム設計 126
  127. テーブルの分割 関数従属性 • キーに従属するデータは同じテーブルに • この原則だけだと、テーブルが肥大化しがち 発生時点で分解 • 事実の発生した時点が異なれば別テーブルにわける 計算従属性 • 計算単位ごとに、計算に必要な事実を別テーブルに分ける ○ 商品番号に従属し、かつ、価格計算に関係にあるカラムだけのテーブル × 価格以外に、カタログ情報や在庫情報を持つ肥大化した商品マスター 2019/3/22 ©有限会社 システム設計 127
  128. 分離・独立を段階的に発展させる テーブル → スキーマ → データベース いきなりデータベース単位の分割を検討しない 1. 小さなテーブル単位に役割を分け、利用特性を明確にする 2. 同じ特性のテーブルをスキーマでグルーピング 3. スキーマ単位の参照権限・更新権限を徹底する 4. 独立性の高いスキーマを別データベースへの切り出しを検討する 2019/3/22 ©有限会社 システム設計 128
  129. 記録と参照、事実と導出結果の分離 2019/3/22 ©有限会社 システム設計 129 事実の記録 事実の複製 導出結果 (残高,状態,集計) イミュータブル イミュータブル ミュータブル INSERT SELECT SELECT 永続化を保証する 事実から再生可能 事実から再生可能 複製 delete/ insert created_at updated_at
  130. ドメイン駆動設計 マイクロサービスへの分割を目的とはしていない 良い設計(適切な関心の分離と変更容易なモジュール構造)を目指す • シンプルなサービスへの分割に進化していく • シンプルなデータベース構造に進化していく • その結果、マイクロサービス化をやりやすくなる 実際に配置・運用をマイクロサービスに分割するかは、要件しだい • マイクロサービス化のトレードオフを検討する • 不必要な複雑さを持ち込まない 2019/3/22 ©有限会社 システム設計 130
  131. 全体のまとめ 2019/3/22 ©有限会社 システム設計 131
  132. 話した内容 2019/3/22 ©有限会社 システム設計 132 ドメイン駆動設計の考え方 ドメイン駆動設計を理解する三つのキーワード エヴァンス本のススメ レガシーに立ち向かう マイクロサービスとドメイン駆動設計
  133. 変更を楽で安全に 2019/3/22 ©有限会社 システム設計 133 変更が楽で安全 ビジネスの要求 開発スピード 開発コスト 運用コスト 性能改善 セキュリティ向上 使いやすさ
  134. ビジネスルールの記述が中核の関心事 プレゼンテーション層の モジュール群 アプリケーション層の モジュール群 データソース層の モジュール群 ビジネスルールを 記述したモジュール群 利用する 2019/3/22 ©有限会社 システム設計 134
  135. 2019/3/22 ©有限会社 システム設計 135 ドメインロジック → ビジネスルール ドメインモデル → 計算モデル オブジェクト指向 → 型指向のプログラミング
  136. ビジネスルールのモデリング Fact 事実の表現 ビジネスの状況の記録や通知に使う値の種類 ・ 数値、日付、場所、識別番号、名称、… Rule Factを使った 計算や判定のロジック 計算式 同一性の判定式 大小の比較式 Goal 知りたいこと 計算結果や判定結果を表現する値の種類 ・合計金額、予定日、残数、… ・出荷可否、受付可否、割引種類、… 2019/3/22 ©有限会社 システム設計 136
  137. Fact-Rule-Goalで記述する 3つの設計パターン 値オブジェクト ロジックを持ったenum コレクションのカプセル化 2019/3/22 ©有限会社 システム設計 137
  138. ビジネスルールの3つの源泉 価値提供の約束と支払いの約束 ビジネス活動の連鎖/約束の連鎖 競争優位の獲得策/競争劣位の防止策 契約 バリュー チェーン 事業運営 ポリシー 2019/3/22 ©有限会社 システム設計 138
  139. エヴァンス本の構成 2019/3/22 ©有限会社 システム設計 139 第1部 ドメインモデルを 機能させる 第2部 モデル駆動設計の 構成要素 第3部 深い洞察に向かう リファクタリング 第4部 戦略的設計 1章~3章 4章~7章 8章~13章 14章~17章 概論と基本事項 ここだけでは役に立たない 役に立つモデルを 手に入れるための 実用的な設計技法 大規模に適用する 長期的に取り組む ための技法
Publicité