Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

ドメイン駆動設計とは何か 【入門編】

7,388 views

Published on

前半は、ドメイン駆動設計を特徴づける4つのポイントを、後半は、エヴァンス本の構成を俯瞰しながら、解説してみました。
gunma.web #30 での発表資料。

Published in: Software
  • Be the first to comment

ドメイン駆動設計とは何か 【入門編】

  1. 1. ドメイン駆動設計とは何か 【入門編】 DDD Alliance 増田 亨 Gunma.web #30 2017-1-20
  2. 2. 自己紹介 コード例 :https://github.com/system-sekkei/isolating-the-domain ブログ:システム設計日記 http://masuda220.jugem.jp/ https://www.slideshare.net/masuda220/ コードを書くのが楽しくて、作ったソフトウェアを使ってもらえるとうれしい、どこにでもいる技術者 2
  3. 3. ドメイン駆動設計とは何か What is Domain-Driven Design 3
  4. 4. お話しする内容 ドメイン駆動設計とは何か 考え方とやり方の特徴 エヴァンス本の概略 第1部 ドメインモデル 第2部 モデル駆動設計 第3部 深いモデル 第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 第1部 第2部 第3部 第4部
  14. 14. 第1部 ドメインモデルを機能させる 開発者がドメインを学び(1章) 関係者で要点を意見交換しながら 意識を合わせ(2章) 見極めた要点(モデル)を コードで表現する(3章) 14
  15. 15. 第1部 要約 • 第1章 知識をかみ砕く – ドメインを継続的に学習する – ドメイン知識が豊富な設計 – ドメインを深く理解する • 第2章 コミュニケーションと言語 – 言葉による意見交換/意識合わせ – 声に出してモデリング – 略式のUML図による議論の基盤/手がかり • 第3章 モデルと実装を結びつける – モデルと実装を一致させる – そのための技法:オブジェクト指向 – モデリングと実装をシームレスな活動にする
  16. 16. モデルと実装を一致させる (3章)
  17. 17. モデル • 選び抜いた重要な側面 • 蒸留された本質的な知識 • 全体を形づくる主要な骨 組み 17
  18. 18. モデル • 選び抜いた重要な側面 • 蒸留された本質的な知識 • 全体を形づくる主要な骨 組み 実装 • 大量かつ網羅的な記述が • 重要ではないが、省略は できない細部の記述 • 肥大化したコード、重複し たコードとの戦い 18
  19. 19. モデル • 選び抜いた重要な側面 • 蒸留された本質的な知識 • 全体を形づくる主要な骨 組み 実装 • 大量かつ網羅的な記述が • 重要ではないが、省略は できない細部の記述 • 肥大化したコード、重複し たコードとの戦い モデルと実装を関連づけることで、実装が整理され、見通しが良くなる 実装からフィードバックすることで、モデルが実用的になる 19
  20. 20. モデルと実装を一致させる技法 オブジェクト指向 判断/加工/計算ロジックの整理整頓 手続きに名前をつける(メソッド) メソッドのグループに名前をつける(クラス) ユーザ定義の型をつくる(クラス) 同じメソッド名で異なる型に対応する(多重定義) 型の関係を構造化する(部分型) 異なる型に使えるロジックの一元化(型パラメータ) 20
  21. 21. モデルと実装を一致させる技法 ユーザ定義型 基本のデータ型、標準ライブラリは汎用目的 値の範囲が広すぎる 使えるメソッドが多すぎる ドメイン特化の独自の型を用意する/見つける 値の範囲を限定する できる操作を限定する ドメインの関心事とクラス名が一致する(一致させる) わかりやすい 変更の影響範囲が、ドメインの感覚と一致する 21
  22. 22. 第2部 モデル駆動設計の構成要素 ドメインロジックの 置き場所を定める(4章) モデルの要素を オブジェクトで表現する基本パターン(5章) モデルと実装の一致を難しくする問題の 傾向と対策(6章) モデル駆動設計の具体例(7章) 22
  23. 23. ドメインロジックの置き場所を定める (4章)
  24. 24. プレゼンテーション層 データソース層 アプリケーション層 ドメインロジックの置き場所を独立させる @Controller @Service @Repository ドメインモデル ここを インクリメンタルに 成長させる ドメインオブジェクトの ライブラリ ドメインロジックを ここに集める 24
  25. 25. モデル要素を表現する基本パターン (5章)
  26. 26. モデル要素を表現する基本パターン • エンティティ – 「識別」という関心事の表現 – 現実世界では、関心事をどうやって識別しているか – それを、どうやって実装に反映するか • 値オブジェクト – 現実世界では、どんな値に関心があるか – その値に必要な判断/加工/計算のロジックは • サービス – 値(状態)を持たないロジックだけの表現 – エヴァンスは、実践的なテクニックの一つといってい るが …
  27. 27. モデル要素を表現する基本パターン (エヴァンス本にない内容) • コレクションオブジェクト – どんなコレクション(要素のグループ、一覧)に関心が あるか – そのコレクションに対してでどんな判断/加工/計算 が必要か • 区分オブジェクト – 場合ごとのルールの違いはどうなっているか • 複雑さの核心になることが多い – どうやって表現するか • strategyパターン/stateパターン • Java enum型(サービス
  28. 28. モデルと実装の一致を難しくする問題 その傾向と対策 (6章)
  29. 29. モデルと実装の一致を難しくする問題 • オブジェクトの永続化 – 可能であれば、ドメインオブジェジェクトは、メモリ上に永遠に存在していてほしい – それができない場合、どうするか? – 関心事と永続化の実装を分離する • Repository をインタフェースで宣言 • ドメインオブジェクトとテーブルのマッピングの外部化 • テーブル設計とオブジェクト設計の分離 • オブジェクトのネットワークの複雑化 – オブジェクトの参照関係の広がり/要点がぼやけてくる – どこかで断ち切る – 整合性とそれを維持するロジックに注目する( Aggregate 集約の設計) – 参照関係の復元は、サービス層で行う • (エヴァンス本には書いていないが) – 画面の複雑さがドメインオブジェクトの集約(Aggregate)に持ち込まれがち – Aggregteをデータのコンテナにしないことが基本 入門編としては、難易度が高いが、必ずぶつかる問題 … ここでモデル駆動設計がだいなしになっている場合が多い…
  30. 30. 第3部 より深い洞察に向かうリファクタリング ブレークスルー(8章) 暗黙的な概念を明示的に(9章) しやなかな設計(10章) 分析パターンの適用(11章) デザインパターンを関係づける(12章) より深い洞察に向かうリファクタリング(13章) 30
  31. 31. ブレークスルー (体験から)
  32. 32. ブレークスルー • 要点が見つかった • 要点をうまくコードで表現できた (良い名前が見つかった) • あちこちのコードがすっきりした • 修正が簡単だった(予測できた) – ロジックの追加や変更 – 区分の追加や変更
  33. 33. ブレークスルーの助走 • 違和感への気づき – 理解がずれている感 – コードのごちゃごちゃ感 – 忘れないようにする • リファクタリングの基本の繰り返し – 長いメソッドからメソッドを抽出 – 大きなクラスからクラスを抽出 – その時の抽出単位と名前付け(暗黙から明示へ) – 値オブジェクト、コレクションオブジェクト、区分オブ ジェクトによる整理
  34. 34. ブレークスルーが起きやすい時 • 区分の構造のリファクタリング – 複数の分類軸が混在しているケースが多い – 区分構造が整理できると、区分オブジェクトにデータ やロジックを寄せやすくなる • 画面構造、テーブル構造の影響からの脱却 – ドメイン層のパッケージ構造 – クラス構造(特に Aggregate) – サービス層のメソッドの単位、引数、返す型 – リポジトリの単位、メソッドの引数、返す型
  35. 35. 第4部 戦略的設計 境界づけられたコンテキストとコンテキス トマップ(14章) コアを蒸留する技法(15章) 大規模な構造(16章) 戦略をまとめあげる(17章) 35
  36. 36. 第4部 戦略的設計 基本はいっしょ (時間がかかる) (範囲が広い) ドメインに焦点を合わせる モデルと実装を一致させる インクリメンタルに設計する 会話とラフスケッチ 36
  37. 37. おまけ 境界づけられたコンテキスト 異なるコンテキスト間のマッピング
  38. 38. 文脈の違いの具体例 • ソフトウェア設計の考え方とやり方 • 意見交換、情報交換が難しい • 同じ言葉を使っていても、意図がうまく伝わら ない • プログラミングや設計は、開発者にとって、目 の前の生々しい課題 • 各自の言葉の使い方、とらえ方が一致しない
  39. 39. 文脈の違い • ソフトウェアの対象分野(ドメイン) • 働き方(自社、受託/委任、フリーランス、…) • 技法とその経験/習熟度 – 分析技法 – 設計技法 – 開発プロセス • 利用技術 – 言語 • 型付けの違い、モジュール化の構文の違い – フレームワーク/ライブラリ – 実行環境
  40. 40. コンテキストのマッピング • 境界づけられたコンテキスト – それぞれの文脈(同じ言葉が同じ意味で通じる範 囲)を特定する • 異なるコンテキスト間のマッピングを試みる – 共同作業(目的、利害が一致する場合) …. この中間にいろいろなパターンがある – 別々の道(目的が異なり、利害も対立する場合)

×