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.

「ドメイン駆動設計」の複雑さに立ち向かう

26,647 views

Published on

関西DDD.java ドメイン駆動設計の原則、全17章の要点、実践してみて学んだこと

Published in: Technology
  • Be the first to comment

「ドメイン駆動設計」の複雑さに立ち向かう

  1. 1. 「ドメイン駆動設計」の 複雑さに立ち向かう 2015年9月4日 増田(@masuda220) ギルドワークス株式会社 取締役 有限会社システム設計 代表 DDDアライアンス 設立メンバ 関西DDD.java スタートアップスペシャル【大阪 9/5】
  2. 2. そんな人のために …そんな人のために … ・読み解くのが困難 ・実践でどう活用するか迷っている ・やってみたがうまくいかない
  3. 3. アジェンダ • 考え方と背景 「まえがき」と「結論」から • 第1部 ドメインモデルを機能させる • 第2部 モデル駆動設計の構成要素 • 第3部 より深い洞察へ向かうリファクタリング • 第4部 戦略的設計 理解の鍵となるところに焦点をあてて 現場での苦労や失敗を踏まえて
  4. 4. 考え方と背景 「まえがき」と「結論」から
  5. 5. 「ドメイン駆動設計」とは 厳しい現実の中で、ソフトウェア設計を習得しよ うと奮闘してきた技術者の物語。 不完全な状況の中で、抽象的な設計原則を、 現実のソフトウェアに適用するための助言。 「日本語版への序文」 by エリック・エヴァンス エヴァンスは、ソフトウェア開発の成功も失敗も味わってきた。 この本は、エヴァンスが成功と失敗の両方から学んだ教訓を伝 えている。 「序文」 by マーチン・ファウラー
  6. 6. エヴァンスの取り組み この二つを組み合わせて、ソフトウェア開発 に取り組んだ。 その成功と失敗の経験から学んだことをまと めたものが「ドメイン駆動設計」。 オブジェクト指向 エクストリームプログラミング
  7. 7. 「ドメイン駆動設計」の想定読者 • 「オブジェクト指向」と「エクストリームプロ グラミング」に、ある程度の知識がある技 術者 • 「オブジェクト指向」と「エクストリームプロ グラミング」の原則を、実際のアプリケー ション開発に適用しようとして、理屈通り にいかないことを経験した技術者 「まえがき」から
  8. 8. オブジェクト指向 エクストリームプログラミング 前提となる知識と経験
  9. 9. オブジェクト指向 エクストリームプログラミング 前提となる知識と経験 私自身は、「ドメイン駆動設計」を初めて読んだ時は、 DOA/手続き型/ウォータフォール系の技術者。 この二つはある程度の知識はあったが未経験。読んでも良くわ からないことがいっぱいあった。 「オブジェクト指向」と「エクストリームプログラミング」を勉強し、 現場でいろいろ挑戦しているうちに「ドメイン駆動設計」の考え 方が理解できるようになってきた。
  10. 10. 勉強になった本 Wabi Sabiを読み解く オブジェクト指向 エクストリームプログラミング 適応型のソフトウェア開発
  11. 11. オブジェクト指向の「変更容易性」 エクストリームプログラミングの「変化適応性」 変化に「適応」する技術
  12. 12. オブジェクト指向の「変更容易性」 エクストリームプログラミングの「変化適応性」 • 「エクストリームプログラミング」は「オブジェクト 指向」のコミュニティで生まれ育った • オブジェクト指向の「変更容易性」が、「適応 型」の開発スタイルをささえている • 相互に補強しあう関係 変化に「適応」する技術
  13. 13. オブジェクト指向の「変更容易性」 (どのパラダイムでも同じだけど) • 抽象データ型/段階的な抽象化 – プログラムを人間の発想に近づけると扱いやすい • モジュラープログラミング – 独立性の高い部品に分けると扱いやすい – 関連するデータと操作は、ひとつのプログラミング単位に • メッセージング – 部品の組合せを柔軟に変更できると扱いやすい – sender/receiver/dynamic routing – Javaだとうまく実現できていないアイデア • メッセージングの考え方の参考 • Erlang, EIP:Enterprise Integration Patterns, マイクロ サービス, …
  14. 14. LocalDate クラス 日付を汎用的に扱う手段 Java APIのレイヤ int year short month short day LocalDateの内部 Java言語仕様のレイヤ if( day > 31 ) … DateOfBirth クラス 「誕生日」に用途を限定した独自定義クラス 「ドメイン層」の一級市民(ドメインオブジェクト) 人間の発想 コンピュータの 仕組み 抽象データ型/段階的な抽象化 人間の発想に近づける Boolean 今月が誕生月() Days 誕生日まであと何日() plusDays() plusMonths()
  15. 15. 「適応型」のソフトウェア開発 開発の スタイル 方法論 ソフトウェアの 最終形(着地点) 開発サイクル 予測型 ウォータ フォール 事前に定義 厳密に定義 固定 分析/設計/製造 反復・ 漸進型 RUP それなりに定義 反復ごとに精緻化 方向付/推敲/作成/移行 各フェーズで分析/設計/製造を、 N回「反復」する 適応型 XP スクラム YAXP ざっくりと定義 日々更新 日、週、春夏秋冬 (人間の生活リズム)
  16. 16. エクストリームプログラミング 変化に適応する技術 • 「言葉」を使ったコミュニケーションと協同作業 – 「変化」を知覚する – 「変化」への対応を相談する – 方向や歩調にずれがないか確認して調整する – お互いの行動にムリやムダがないか確認して調整する • フィードバック – 動くプログラムで実験し確認 – しゃべってみた感じ/聞いてみた感じ • 必要のない複雑さの持ち込み防止 – コードによる確認(実験) – 言葉による意見交換
  17. 17. 日々、変化し成長していく • 毎日、方向付け/推敲/作成/移行を行う。 – 午前は、「方向付け」と「推敲」のためにコードを書く – 午後は、がっつり「作成」する – 夕方、今日の成果を「配置」する – 毎日、フィードバックを受け取る • 最終の着地点と進行方向を確認しながら進む – 何か新しいことが起きていないか、毎日、見直す – 進む方向がずれていないか、毎日、見直す – 週で見直し、季節で見直す。3年、5年、50年。 • 「変化」を知覚したら「チーム」で機敏に対応する – 方向の微調整かもしれない – 大きな方針転換かもしれない – 変えるべき時は大胆に、チーム一丸で、「言葉」を使って
  18. 18. OO+XP=ドメイン駆動設計? • 「ドメイン駆動設計」は、オブジェクト指向とエ クストリームプログラミングを組み合わせた開 発の体験談 – エクストリームなオブジェクト指向プログラミング • そして「ドメイン駆動設計」は、OO+XPの考 え方とやり方の「強調」する点をずらしている by エリック・エヴァンス
  19. 19. 「ドメイン駆動設計」が強調する点 • 「ドメイン」に焦点をあてる • 「モデル」と「コード」の歩調を合わせ ながら、少しずつ「成長」させる • 「言葉」を使って「チーム」でモデルと 設計の「改良」を続ける この三つを組み合わせて開発する体験談が「ドメイン 駆動設計」の特徴であり魅力。
  20. 20. 「ドメイン駆動設計」の理解の鍵 • 「ドメイン」に焦点を当てるとは、具体的にどう いうことか • 「モデル」と「コード」の歩調を合わせるとは、具 体的にどういうことか • 「言葉」を使って、「チーム」でモデルと設計を 「改良」するとは、具体的にどういうことか • そのために「オブジェクト指向」と「エクストリー ムプログラミング」の考え方をどう実践するか
  21. 21. 俯瞰 • 第1部 ドメインモデルを機能させる 「ドメインモデル」を中心にすべてを組み立てる 第2部/第3部/第4部に一貫するテーマ • 第2部 モデル駆動設計の構成要素 基本スキル(第3部と第4部の土台づくり) このレベルは「必要」そして「不十分」 • 第3部 より深い洞察へ向かうリファクタリング 実際に「役に立つモデル」を育てる • 第4部 戦略的設計 より広い範囲で、より長期的に取り組む
  22. 22. ここに着目して読むと発見が多い • 少しずつ変化し成長していく様子 – 「モデル」/「設計」/「チームが使う言葉」 – 成長の様子がわかりやすい箇所 1章、7章、8章、13章、15章、結論 • ソフトウェア開発の「厳しい状況」の体験談 – 困ったこと – 難しかったこと – 失敗したこと – その時の選択肢、選択の理由
  23. 23. 第1部 ドメインモデルを 機能させる
  24. 24. 「ドメイン駆動設計」の3原則 • 第1章 知識をかみ砕く • 第2章 コミュニケーションと言葉の使用 • 第3章 モデルと実装を結びつける
  25. 25. どういう意味? 同じ理解? • ドメイン • モデル • モデリング • ドメインモデリング カタカナ言葉は意図伝達で問題を起こしやすい ぎこちなくても日本語にしたほうがまちがいが減る
  26. 26. ドメイン • ソフトウェアを利用する人たちの 「活動」と「関心事」 – ソフトウェアの利用は、活動全体の一部 – 関心事の焦点は、ビジネスや業務上の成果 • ドメインではないこと – ソフトウェアを作る活動そのもの – コンピュータの仕組みや挙動 – 画面仕様書/機能一覧/ユーザーストーリー/…
  27. 27. ドメインとソフトウェア 利用する人たちの 活動と関心事 ソフトウェア
  28. 28. 活動の目的/背景 文脈 利用する人たちの 活動と関心事 ソフトウェア
  29. 29. ドメインのモデリング • 利用する人たちの「活動」と「関心 事」を要約する • 「活動」の要約 –アクティビティ図/業務フロー図 • 「関心事」の要約 –概念モデル図 (クラス図/パッケージ図)
  30. 30. モデル • 膨大な知識を「要約」した シンプルでわかりやすい説明 • モデリングのスキル=「要約力」 –重要な要素を発見する力 –本質的でないものを削る力 –厳密に組み立てる力
  31. 31. ドメインモデル • ソフトウェアを利用する人たちの「活動」と 「関心事」の本質を簡潔に表したもの • 表現 –チームの会話に登場する「言葉」 –ラフスケッチ –コード –(文章や図)
  32. 32. 主題:モデルを活用する 第2章 言葉を使った意図の伝達 第1章 ドメインの知識をかみ砕く 第3章 モデルと実装を結びつける ドメイン モデル ドメインの 膨大な情報を かみ砕き、蒸留して 重要な関心事を 鋭く説明する 選び抜かれた ドメインの重要な関心事を コードで表現する 会話を繰り返して 「要約」を改善する (重要点を明確にする) 「重要な語彙」をメンバーで 合意する/共有する
  33. 33. 第1章 知識をかみ砕く • プリント基板(PCB)設計ツールの開発経験 • (経験から学んだ)効果的なモデリングの要素 • 知識のかみ砕き • 継続的な学習 • 知識豊富な設計 • 深いモデル 変化と成長の様子
  34. 34. 出発点 図というよりは、頭の中のイメージ ほとんど何もわかっていない
  35. 35. 知識の広がり PCB設計者と会話をしながら 聞き取れる語彙がちょっと増えてきた
  36. 36. ある程度理解できたら 「モデル」が役に立つかコードで実験 だいぶ意思疎通ができるようになってきた段階のモデル PCB設計者の関心事をうまく説明し、かつ、 設計として役に立ちそうか実験
  37. 37. 本質的な関心事にたどり着いた 深いモデル PCB設計者の本質的な関心事をうまく説明しつつ、 ソフトウェアの基本構造としてそのまま使える「深いモデル」
  38. 38. 知識をかみ砕きながら モデルとコードを少しずつ成長させる 少しずつ成長していく感じを掴む
  39. 39. 第1章 まとめ • 「モデル」の成長する様子 • 知識のないところから出発する • 語彙を増やす • 正しい言い方(正しい意味)を覚える • コードでも表現してみる • 本質的な関心事を探す • 継続的に学ぶ • 知識をかみ砕いた成果が「ドメインモデル」 – 利用する人たちの「活動」と「関心事」の本質を「簡潔」 に表現した言葉・図・コード
  40. 40. 第2章 コミュニケーションと言語の使い方 • ユビキタス言語 – 例:貨物輸送プログラム • 声に出してモデリングする • 1つのチームに1つの言語 • ドキュメントと図 • 説明のためのモデル
  41. 41. ユビキタス言語 • いつでも、どこでも、誰とでも – 技術者だけで話す時に、「利用する人たちの関心事」の言 葉が自然にでてくれば本物 • 一つ言葉を同じ意味で – 要求仕様や画面に現れる「用語」と、ソフトウェアを利用す る人たちが使う「言葉」の意味の食い違いに注意 – 「顧客」「注文」「売上」 • 一つの意味を同じ言葉で – 同じ意味に思える「別の言葉」に敏感に – 「要請」「依頼」「リクエスト」 • ユビキタス言語の中で、「特に重要な語彙」を選び抜い たものが「ドメインモデル」
  42. 42. 声に出してモデリングする • 良いモデルを見つける実践的な方法 – 語尾まで明瞭に語ってみる – しゃべりにくい – 要点が聞き取れない • 復唱ゲーム – 同じことを、別の人/別のタイミングで「同じ」に語れるか – 同じ言葉、同じ言い回しにならない • 他の表現との不一致に敏感に – コード、図、コミットログ、チャット、メールなど書かれた言葉 – 笑っちゃうくらう一致していない(意味、重要度) • チームのドメインの理解が進み、重要な関心事がはっきりし てくると、よどみなく同じ言い回しがでてくるようになる
  43. 43. 一つのチームに一つの言語 • チーム内では一つ言葉を同じ意味で – 要求仕様や画面に現れる「用語」と、ソフトウェアを利 用する人たちが使う「言葉」の意味の食い違いに注意 • チーム内では、一つの意味は同じ言葉で – 同じ意味に思える「別の言葉」に敏感に • 第4部の「境界づけられたコンテキスト」や「継続 的な統合」の基本原理 • エクストリームプログラミングでは、ドキュメントの 代わりに「会話」で意図を伝達する
  44. 44. 言葉たいせつ • 「エクストリームプログラミング」では、言葉を 使った会話がドキュメントの代わり • 意図伝達の主要な手段 • 「言葉」は、そのままクラス/メソッド/パッ ケージの候補 • あらゆる場所で同じ言葉を – 会話/チャット/メール/コミットログ/ソースコード – 早期に食い違いを発見できるように
  45. 45. 言葉たいせつ •開発者が、利用者の「重要 な関心事」をよどみなく語り 始める安心感 •開発者が、技術用語しか 使わない恐怖感
  46. 46. 第2章 まとめ • 言葉たいせつ • みんなが持っているすばらしい能力 • それをとことん活用する
  47. 47. 第3章 モデルと実装を結びつける • モデル駆動設計 • モデリングパラダイムとツールによるサポート • 骨格を見せる なぜモデルがユーザにとって重要なのか? • 実践的モデラ
  48. 48. ドメイン駆動設計の「モデル」 • 初期の分析を支援するだけでなく、設計にお いて土台になるモデル – 要点を選び抜いた簡潔な表現 • 分析と設計の両方に役立つ「モデル」を探す – 簡単には見つからない – 最初からは見つからない – 少しずつ実験し、学習し、良いモデルに育てていく – 言葉による実験/コードによる実験 – 見つけることの効果/見つからないことのリスク
  49. 49. (ドメイン層の)骨格を見せる なぜモデルがユーザにとって重要か? • 「モデル」が、利用者の「重要な関心事」を反映し ていれば、主要なクラスとその関係は、利用者に とって理解できる – オブジェクトの構造を画面レイアウトや画面遷移的に 説明すると、会話しやすい • とんでもない勘違いを早めに発見できる – わかっていないことの発見 • 利用者がソフトウェアの潜在的な可能性に触れる ことができる – より本質的な要求の発見の機会の広がり
  50. 50. 実践的モデラ • コードを書かない人間が、利用者の 活動や関心事を深く理解しても、良 いソフトウェアは生まれない • コードを書く人間が、ドメインの知識 をかみ砕き、重要な関心事を正しく 理解するのが、もっとも確実で、もっ とも効果的なソフトウェア開発手法
  51. 51. 第3章 まとめ • ドメインの理解にも、コードの設計にも役に立 つ「モデル」(要約)を探す • 「モデル」と一致した「コードの骨格」は利用者 にも理解できる • コードを書く人間がドメインを深く理解するのが、 もっとも確実でもっとも効果的なソフトウェア 開発手法
  52. 52. 第2部 モデル駆動設計の 構成要素
  53. 53. 主題:モデルと実装の協調を保つ • 第4章 ドメインを隔離する • 第5章 ソフトウェアで表現されたモデル • 第6章 ドメインオブジェクトのライフサイクル • 第7章 言語を使用する:応用例
  54. 54. 主題:モデルと実装の一致 • 非常に難しい – 頭の中の理解がコードで表現できていない – そこに気づかない • 無意識で高速な翻訳能力 • モデルとコードの不一致 – 的はずれなソフトウェア – 構造がねじれたソフトウェア – 変更コストの増大⇒成功が止まる⇒変化に適応できない • 何をすべきか – ドメインの隔離の徹底 – モデルをコードで表現する基本の徹底 – ドメインオブジェクトのライフサイクルの複雑の分離
  55. 55. 第2部は基礎練習 • ボールを蹴って止める基本の練習 • 相手に囲まれても確実にできるように • 90分走りぬいたあとでも確実できるように • ぬかるんだピッチでも確実にできるように • 第2部の構成要素をどんな状況でも、確実に 使えるスキルが、「第3部 深いモデル」、 「第4部 戦略的設計」を実践する土台になる。
  56. 56. 第4章 ドメインを隔離する • レイヤ化アーキテクチャ • ドメイン層は「モデル」が息づく場所 • 利口なUI(アンチパターン) • その他の隔離
  57. 57. レイヤ化アーキテクチャ
  58. 58. ドメイン層と「モデル」 • 「モデル」をドメイン層の「コードの骨格」とする – 「重要な関心事」の「コードの骨格」を中心に、さま ざまなドメインの知識を表現したコードを配置する • ドメイン層にドメインの知識を集め続ける – ドメイン層が知識豊富になるほど、深いモデルの 発見の可能性が広がる • 知識が貧弱なドメイン層から深いモデルは生まれない – 画面やSQLに書き加えられがちな、ビジネス知識を 丹念に、継続的に、ドメイン層に移動する努力
  59. 59. ドメインの「隔離」 • 表面的な分離は簡単 • 現実 – コントローラ層やページ記述にしみだした業務知識 • if(未承認なら) setDisable() – 複雑なSQL文にまぎれこんだ業務知識 • NOT EXIST xxx OR customer.type = 1 • 業務知識のまぎれこみに敏感になる – アンチパターンを覚える – 継続的にリファクタリングする • 画面駆動の開発はコントロールや画面でドメイン知識を記述するア ンチパターンが横行する • データベースのフラグと区分もアンチパターンの宝庫
  60. 60. ドメイン層にロジックを集める工夫 • 2ステップビュー • 「操作」オブジェクトとボタン表示 • 動的SQL生成でドメインオブジェクトを活用する …
  61. 61. 2ステップビュー • ドメイン層とプレゼンテーション層の関係 – ビューを「論理構造」と「物理表現」の2段階で生成 • Step1:ドメインオブジェクトが論理構造を返す – 例えば、List<String> • Step2:プレゼンテーション層のヘルパークラス が、論理構造を物理構造に変換する – 例えば、 <tr> </tr> – 例えば、<br/>の挿入
  62. 62. 操作モデルとボタン表示 • 状態や権限による操作の違い – ビジネスルール – プレゼンテーション層での if文はアンチパターン • ActionList オブジェクトをプレゼンテーション 層に渡す • その情報を元にプレンゼンテーション層が、ボ タンを出し入れする – ビジネスルールに変更があってもプレゼンテーショ ン層のコードはそのまま
  63. 63. 動的SQLの記述 • ドメインオブジェクトに論理構造を持たせる – 動的な AND/OR 条件 – 動的な ORDER BY 句 • ドメインオブジェクトが返す論理構造をSQLに マッピングする – ORDER BY #orderHistory.byPriority() – ヘルパークラスがList<優先項目>を、SELECT の カラム名リストに変換する
  64. 64. 第4章のまとめ • ドメインを隔離する • 形式的なコーディングルールや、フレームワークの 導入は隔離の「出発点」 • ちょっとした修正で、ドメインの知識がドメイン層 以外に拡散する危険を察知する嗅覚を磨く • プレゼンテーション層からドメインロジックを抽出し てドメイン層に移動し続ける • データソース層からドメインロジックを抽出してドメ イン層に移動し続ける
  65. 65. 第5章 「モデル」をプログラムで表現する • 関連 • エンティティ • 値オブジェクト • サービス • モジュール • モデリングパラダイム
  66. 66. 第5章の問題意識 • モデルとコードの一致は難しい • 「モデル」は、人間の関心事の要約 – 意図を伝達するために「自然言語」を使う • プログラミング言語(人工言語)で、どうやって人 間の関心事をそのまま表現するか? – 細かい点に気を配らないと、すぐに「モデル」と「コー ド」が離れていく – モデル(重要な関心事)と実装が分離すると、ソフト ウェアが的はずれなものになり、変更がたいへんにな る – ソフトウェアの成長が止まる
  67. 67. モデルをコードで表現する工夫 • スリムな「エンティティ」 • 部品の独立性を高めた「値オブジェクト」 • 操作の自然な置き場所を見つける「サービス」 • 重要な関心事「ファーストクラスコレクション」 • ビジネスルールの表現手段「区分オブジェクト」
  68. 68. ドメイン駆動設計
  69. 69. 何が違うのか? 「関連」を考えなくて良い 「集約(Aggregates)」を考えなくて良い データベースとマッピングしやすい 「関心事」があいまい(ごった煮) 「関連」の設計と実装が必要 「集約」の設計が必要 データベースとのマッピングが複雑 「関心事」を発見してクラスに抽出
  70. 70. 成長を続ける「適応型」アプローチ • ドメインを学びながら「関心事」を発 見する • 「関心事」をクラスに「抽出」しなが ら、モデルとコードの両方を育てる • ドメインの「関心事」を、さらに深 掘っていくとっかかり – 住所がない場合? – 複数の住所? – 住所がわかる時/変わる時
  71. 71. ドメイン駆動設計のやり方 ボールを蹴って止める基礎技術
  72. 72. 値オブジェクト(Value Objects) • 大きなクラスの「分割」ではなく、重要な「関心事」 を発見し「抽出」する感覚 • 値オブジェクトはメソッドを「知識豊か」にする – 引数の型/メソッドの返す値の型 × String address(long id); ◎ Address of(CustomerId id); • 人間の関心事に近づける努力 – int,String,LocalDateでは、ドメインの「関心事」を 具体的に表現できない – 「顧客」や「住所」など、関心事を表現する独自の「型」 を定義する • 抽象データ型/段階的な抽象化 • ドメインオブジェクト(の型)
  73. 73. エンティティ(Entity) • 太りがち – 見つけやすいドメインオブジェクト(注文、顧客、…) – インスタンス変数を追加 – ロジックを追加 – いろいろな「関心事」がコードに埋もれがち(暗黙知) • エンティティは、とことんスリムにする – 「識別」という利用者の関心事に集中する • 一覧の表示順や検索項目 • 重要な関心事の発見につながる • 例えば同姓同名問題 – 「内容の説明」は「値オブジェクト」にまかせる(議論を 分ける)
  74. 74. ドメイン層の「サービス」 • どの「エンティティ」や「値オブジェクト」に置くべ きか迷うロジックがいろいろでてくてる • そういう時は、そのロジックに名前を付けてク ラスとして抽出してみる(実験) – XxxPolicy – XxxRule – XxxProcedure …
  75. 75. ドメイン層の「サービス」 危険! • 「手続き」にドメインの「関心事」が隠ぺいしがち – 深いモデルの探求の手掛りを見失う • 同じ「ロジック」が複数サービスに重複する – 変更コストがあがる – モデルとコードの「成長の障害」になる • 考え方とやり方 – メソッドの引数と型は「ドメインオブジェクト」にする • long や Stringを使わない – 基本は多態(ルールの場合ごとの切り替え)の道具 – それ以外の場合、リファクタリングの候補としておく • より適切な置き場所を模索を続ける(良いモデルの探求)
  76. 76. その他の有用な構成要素 • ファーストクラスコレクション • 区分オブジェクト 私たちが良く使っているテクニック
  77. 77. ファーストクラスコレクション • ListやSetをラップしたドメインオブジェクト • Products • PurchaseHistory • 「一覧」や「履歴」という関心事の表現手段 – 一覧画面に対応するドメインオブジェクト – 「一覧」は利用者の関心事が集中する場所 – 「一覧」の議論は、重要な関心事の発見の良い機会 • 一覧=SQLで複雑な問合せ? – SQLの抽出条件は単純にして、微妙な抽出や問合せを、オ ブジェクトにやらせる、という選択肢 – どちらがドメインの概念をうまく表現するか/発見できるか – 変更があった時に、どちらが楽で安全か
  78. 78. 区分オブジェクト • 振る舞いを持った Enum • 区分ごとのロジックを別クラスに記述 • Java言語使用に組み込まれた Strategy/Stateパターン 説明とコード例は、googleで 「場合わけの書き方あれこれ」で検索。 または「ソフトウェアデザイン9月号」 場合ごとのルールを理解し表現する道具
  79. 79. モジュール(Packages) • 重要なモデリング要素 – 関連するドメインオブジェクト(の型)のグループ – 利用者の関心事の「境界」を表現する手段 – プログラミング単位 – テスト単位 • 「適応型」のアプローチの対象 – 新しい発見とともに、積極的にパッケージ名/ パッケージ構成を変更し育てていくこと • 「第4部 戦略的設計」の基本ツール
  80. 80. 第5章 まとめ • 「モデル」(利用者の主要な関心事)をプログラ ムで表現する • 「モデル」と「実装」の一致は難しい • そのための基本スキルを体で覚える • 丁寧に地道に続ける • 第3部と第4部の土台 – ほんとうに役に立つのは深いモデルを見つけた時 – 大きな効果がでるのは戦略的に取り組んだ時
  81. 81. 第6章 ドメインオブジェクトのライフサイクル • 集約 • ファクトリ • リポジトリ
  82. 82. 問題意識と解決の工夫 • コードが複雑になりがちな – オブジェクトのライフサイクル管理 • 生成/格納・再構成/修正/削除 – オブジェクト間の整合性の管理 • 「モデル」の表現からこの複雑さを取り除く – 「モデル」と「実装」の関係を単純明確に保つ • ドメインオブジェクトのネットワーク構造と「集約」 • オブジェクトの生成と「ファクトリ」 • 必要なオブジェクトを簡単に入手する「リポジトリ」
  83. 83. 「集約」 • ドメインオブジェクトのネットワーク構造 – 利用者の「活動」や「関心事」の結びつきを反映す るので、必然的に複雑になる • 「集約」という単位を導入して、複雑なネット ワークに「構造」を導入する(設計上の問題) – 「ひとかたまり」として扱うべき境界を探す – 言語仕様上に表現手段がないのが難点 – 開発の単位
  84. 84. 「ファクトリ」 • オブジェクト(の集約)の生成 – エンティティ(集約のルート)が自分で持つと、エンティ ティ本来の関心事があいまいになる – 「コード」が複雑になり「モデル」との対応があいまいに なる • 生成ロジックの置き場所 – 「集約のルート」のファクトリメソッド – 「集約の生成」に関わるオブジェクトのファクトリメソッド – コンストラクタ – 独立したファクトリクラス …
  85. 85. 「リポジトリ」 • 必要なオブジェクトの集約を入手する • あたかもすべてのドメインオブジェクトがメモリ 上にあるように設計する – データベース設計やORマッピングをいったん忘れる – interface 宣言で実装を分離する • やりたいことをシンプルに宣言する • 注文 findBy(管理番号) • 注文一覧 lookFor(検索条件) • void register(注文)
  86. 86. 第6章の補足(実践例) • 注文Repository#prototype() – データベースのシーケンスを使った管理番号を持ったド メインオブジェクトの生成 – 注文受付番号を持ったドメインオブジェクトを返す – 入力画面に渡す – デフォルト値の設定 • 「トランスファ」インタフェース – 「通知」を表現するモデル要素 – 「記録・参照」を表現した「リポジトリ」と似ている – 実現手段は、データアクセス層で実装する
  87. 87. 第6章 まとめ • ドメインオブジェクトのライフサイクル管理は コードを複雑にする • 「モデル」の表現から、この複雑さを取り除く • 「モデル」と「実装」の関係を単純明快に保つ • 「集約」単位で関心事の境界を明確にする • 「集約」単位で実装の境界を明確にする
  88. 88. 第7章 言語を使用する:応用例 • 4章、5章、6章の「構成要素」を組み合わせ る実戦に近い練習 • 仮想的なチームが要求と実装の問題に対処し ながら「モデル駆動設計」で開発をしていく例 • その過程で生じる「さまざまな問題」と「どう解 決」されるかを見ていく • 読み取るのはたいへん • でも、発見と学びが多い章
  89. 89. 第7章の構成(成長の様子) 1. 貨物輸送システムの概要 2. ドメインを隔離する:アプリケーション層の導入 3. エンティティと値オブジェクトを区別する 4. 輸送ドメインの「関連」を設計する 5. 「集約」の境界 6. 「リポジトリ」を選択する 7. シナリオをウォークスルーする 8. オブジェクトの生成 9. リファクタリングのために立ち止まる 10.輸送モデルにおける「モジュール」 11.新機能を導入する:配分チェック 12.最後に
  90. 90. 第7章はより実戦に近い練習 • 「モデル」と「実装」が育っていく過程とリズム • 「モデル駆動」で設計するということ – 最初に「アプリケーション層」を導入する • 「ドメイン層」の議論を「機能」視点から隔離する • 機能(処理)の詳細化からの設計ではない – 入出力項目(画面帳票)の定義は登場しない • プレゼンテーション層無しのドメイン層の設計と実装 – データモデル/テーブル設計は登場しない • データモデルから独立したドメイン層の設計と実装
  91. 91. 関連・集約・リポジトリ • 第7章の議論のハイライト • 「関連」を設計する – 関連の方向の議論はドメインに対する洞察 – 複雑な実装を避ける(成長容易性の確保) • 「集約」の境界 – ドメインオブジェクトの「かたまり」の定義 – 概念(関心事)の境界の明確化 – 開発単位 • 「リポジトリ」を選択する – 機能視点が登場するタイミング • 検索/選択/登録 …
  92. 92. 第2部は基礎練習 • ボールを蹴って止める基本の練習 • 相手に囲まれても確実にできる • 90分走りぬいたあとでも確実できる • ぬかるんだピッチでも確実にできる • 第2部の構成要素をどんな状況でも、確実に 使えることが、「第3部 深いモデル」、「第4部 戦略的設計」を実践する土台になる。
  93. 93. 第3部 より深い洞察に向かう リファクタリング
  94. 94. 主題:実際に役に立つモデル • 第8章 ブレークスルー • 第9章 暗黙的な概念を明示的にする • 第10章 しなやかな設計 • 第11章 アナリシスパターンを適用する • 第12章 デザインパターンをモデルに関係づける • 第13章 より深い洞察に向かうリファクタリング
  95. 95. 役に立つモデル • ドメインについての深い理解を表現したモデル – 利用者の「主要な関心事」の「明快な表現」 – 表面的な側面を捨て去る – 利用する人たちの要望に機敏に対応できる • 何をすべきか – 「深いモデル」を目指した「リファクタリング」 – 「言葉」を使った発見/実験/改良 – 実験と成長のための「しなやかな設計」の工夫
  96. 96. 第8章 ブレークスルー • ブレークスルーの話し – 悪くないモデルなのだが – ブレークスルー – さらに深いモデル – 冷静な意思決定 – 結末 • 好機 • 基本への集中 • エピローグ:新しい洞察の連鎖
  97. 97. 「8章 ブレークスルー」を読む • ブレークスルーの自分の経験を思い出す – なんだ、こういうことか – お、そうか – 目からうろこ • 変化のリズム – 緩-緩-急、緩ー緩ー急、… • 「緩」 は基本を地道に繰り返し、小さな変化を積み重ねる期間 • 「急」 は大きな変化に冷静に対処する期間 • 大きな変化の時 – 「発見の喜び」と「実験」と「実装」を冷静に制御する – チームで納得して行動する
  98. 98. 第9章 暗黙的な概念を明示的にする • 概念を掘り出す – 言葉に耳を傾ける – ぎこちなさを精査する – 矛盾について熟考する – 文献を読む – 何度でも挑戦する • それほど明確でない概念をモデル化する方法 – 明示的な制約 – ドメインオブジェクトとしてのプロセス • 仕様(Specification)
  99. 99. 概念を掘り出す努力していますか? • 言葉に耳を傾ける • ぎこちなさを精査する • 矛盾について熟考する • 文献を読む • 何度でも挑戦する ドメイン駆動設計の実践のキモ 9章を読みながら、個人やチームで振り返りを
  100. 100. 9章の補足 • 「制約」 – 制約が概念の輪郭の発見の手掛りになる – 制約のなさに「便利さ」ではなく「気持ち悪さ」を感じよう • String/LocalDate/BigDecimal/Collection/ … • 「プロセス」 – オブジェクト指向の苦手な世界 – イベントストリームやリアクティブの考え方が武器になる – 利用者の関心事を表現する武器 • 「仕様」 (Specification) – 述語論理(AND/OR/NOT/EXIST/…) – オブジェクト指向の苦手な世界 • Java 8 Predicate ? – 良い実装の枠組み手に入れると、強力な武器になる – 利用者の関心事を表現する武器
  101. 101. 第10章 しなやかな設計 • 意図の明白なインタフェース • 副作用のない関数 • 表明 • 概念の輪郭 • 独立したクラス • 閉じた操作 • 宣言的な設計 • 設計の宣言的スタイル • 攻める角度
  102. 102. 設計テクニックと言語仕様 • 10章のテクニックは、言語によっては言語仕様の一部 • Javaはなんでもありで、今となっては古い設計の言語 10章のテクニックは意図的に使う必要がある – チームでの共有と実践の工夫 – 「値Object」や「ファーストクラスコレクション」は、10章のテ クニックの合わせ技 – チーム内の意識合わせの良い題材 • 10章の文脈で他の(型重視の)言語仕様を勉強してみ ると役に立つ – Haskell, Kotlin, Swift, … Javaをきらいにならない程度に
  103. 103. 第11章 分析パターンを適用する • 「分析パターン」はゴールではなく出発点 • 「モデル」(重要な語彙)のネタ探し • 「ユビキタス言語」のネタ探し • 「公開された言語」も有用 • その分野の(プログラミングとは関係ない)解 説書や手引書も有用 – 特に「目次」「図表」「用語集」 – 「要約」されているから
  104. 104. 第12章 デザインパターンをモデルに関係づける • デザインパターン – 技術的な側面に焦点をあてているパターン – 動機と解決策が技術的な観点と用語で紹介されてい る • 「ドメイン」の概念を表現する道具として読み直す – 技術的なデザインパターンが、どのようにドメインの問 題に適用できるか? – 「ドメイン」の言葉で、そのパターンの動機と解決策を 説明できるか? • 技術観点とドメイン観点の比較の良い材料
  105. 105. 第13章 より深い洞察に向かうリファクタリング • 開始 • 探求チーム • 先達の技 • 開発者のための設計 • タイミング • 好機となる危機
  106. 106. リファクタリングのきっかけ • コードの複雑さやぎこちなさへの違和感 • 言葉の不一致を感じた時 • 新しい要求がすんなりと既存のコードに適合し ない時 • コードを読んでいて、それを書いた時の理解が 古い/まちがっていことを発見した時
  107. 107. リファクタリングの 方向とタイミングを間違えないために • 選抜チームで取り組む – 変更を先導する人 – 問題を深く考えるのが得意な人 – その領域の経験が深い人 – 強力なモデリングスキルを持つ人 • ユビキタス言語を駆使する – アイデアだし – 言葉による実験 – コードによる実験 • ドメインエキスパートの納得感をたいせつに – エキスパートが納得しない「深いモデル」はありえない – 「正解」を本人が説明できなくても「違和感」は直観できる
  108. 108. 深いモデルへのリファクタリング 実施の意思決定 • 設計が、ドメインに関する「チーム」の現在の理 解を表現していない時 • 「重要な概念」が設計で暗黙的になっている時 (かつ、それを明示的にする方法がわかってい る時) • 設計において「重要な部分」を、よりしなやか にする好機がある時
  109. 109. 第3部 まとめ • 深いモデル – ドメインについての深い理解を表現したモデル – 利用者の「主要な関心事」の「明快な表現」 – 表面的な側面を捨て去る – 利用する人たちの要望に機敏に対応 • 何をすべきか – 「深いモデル」を目指した「リファクタリング」 – 「言葉」を使って「チーム」で発見/実験/改良 – 実験と成長のための「しなやかな設計」の工夫
  110. 110. 第4部 戦略的設計
  111. 111. 第4部 戦略的設計 • 第14章 モデルの整合性を維持する • 第15章 蒸留 • 第16章 大規模な構造 • 第17章 戦略をまとめあげる
  112. 112. 広い範囲で長期的に取り組む • 意思決定がむずかしい – 構成要素が多く、複雑に入り組んだ関係 – 複数のチーム間の交渉など「政治的」な要因の扱い – 巨大で複雑なシステムの「全体的な秩序」の改善 – 巨大で複雑なシステムの「成長を続ける全体」 • 何をすべきか – (このレベルでも)「言葉」を使った発見と改良に取り組む – (このレベルでも)実装と結びつくモデルを探求する • 現場でコードに責任を持つメンバーが中核になって進める – 少しずつ「秩序」を改善する – 少しずつ「全体」を成長させる
  113. 113. 第14章 モデルの整合性を維持する • 境界づけられたコンテキスト • 継続的な統合 • コンテキストマップ • 境界づけられたコンテキスト間の関係 • 共有カーネル • 顧客/供給者の開発者のチーム • 順応者 • 腐敗防止層 • 別々の道 • 公開ホストサービス • 公表された言語 • 象のモデルを統一する • モデルコンテキストの戦略を選択する • 変換
  114. 114. 主題:チーム/言語/意思疎通 • 14章の内容を技術視点で取り組まないこと • 意思疎通や協力関係の問題と解決策 – チーム内の言葉の不整合 – チーム間の言葉の不整合 – チーム間の力関係の影響 • 組織上の関係、契約上の関係、非公式な力関係、… – 例えば • 「境界づけられたコンテキスト」は「言葉の通用範囲」で切り分ける • 「継続的な統合」は、「言葉の不一致」を発見し修正する活動(ツー ルではなく、頻繁な会話) • 費用対効果 – 短期的/長期的/利害関係/費用管理の責任者/… こういう問題に「コード」を書く人間が取り組むことがもっとも効果的
  115. 115. 第15章 蒸留 • コアドメイン • 蒸留の拡大 • 汎用サブドメイン • ドメインビジョン声明文 • 強調されたコア • 凝集されたメカニズム • 蒸留して宣言スタイルにする • 隔離したコア • 抽象化されたコア • 深いモデルの蒸留 • リファクタリングの対象を選ぶ
  116. 116. 「コアドメイン」 中核中の中核を見究める • 中心になる問題に集中し、枝葉末節の海でおぼ れないようにする – 「ドメインモデル」自体が、重要な関心事 – 「ドメインモデル」が複雑になってきた時に、さらに、そ の「中核」部分を見究める活動 – 高度な「要約力」 – すこしずつ、実験とフィードバックを繰り返しながら「コ アドメイン」を識別していく • ビジネスへの影響の大きさ/ソフトウェアの価値
  117. 117. 「中核」を探す準備 • かたまりにわける – モジュールの設計と改善作業 – 汎用サブドメイン • 独立性が高く、一般的な業務知識などをたよりに発見できるモ ジュール – 凝集されたメカニズム • 技術的な関心事の隠ぺいを追求することで発見できるモジュール – 「意図の明白なインタフェース」のみ公開される • それぞれのモジュールの「意図」「役割」を明確にする – 名前 – モジュール間の依存関係 – 「言葉」を使って検証と改良を続ける
  118. 118. 「コアドメイン」の実現 4つのレベル(成長の方向) • ドメインビジョン声明文 – 言葉による「コアドメイン」の実験と改良 – 費用対効果が高い(チームが根本概念を共有する効果) • 強調されたコア – 実装の変更に取り組む前の実験/準備作業 – 既存の「モデル」で重要な点を強調してみる • 本質的なオブジェクトを書きだしたり要約図を描いてみる • ドキュメントがあれば、付箋やマーキングで強調してみる • 隔離されたコア – 重要な要素を、特定のモジュールに集める • 「モジュール」構成のリファクタリング • 抽象化されたコア – 根本的な概念を、クラスやインタフェース宣言に抽出する – 他の詳細が、この抽象化されたコアに依存するように設計する
  119. 119. 第15章 まとめ • コードを書く人間が「中核」の関心事を的確にとらえて いる効果 • 「中核」の関心事が、コードで表現できていることの威 力 • 少しずつ地道な改善活動を「チーム」で続ける – 大勢で、長期的に – 協力のための手段「言葉」 • 費用対効果 – 効果を過剰に想定しない – 費用の過小に見積もらない – しなやかな設計による費用の削減努力 – 言葉による低コストの実験の繰り返し
  120. 120. 第16章 大規模な構造 • 進化する秩序 • システムのメタファ • 責務のレイヤ • 知識レベル • 着脱可能コンポーネントフレームワーク • 構造による制約にどの程度厳しくすべきか • ふさわしい構造へのリファクタリング
  121. 121. 主題:森を見る力 • コードに責任を持つ開発者たちが、全体を俯 瞰し理解する効果 • 大きく複雑なシステムの秩序を少しずつ改善し ていくための手掛りの発見 • 関係者が全体の構造を理解し議論するための 「言葉」を手に入れる効果
  122. 122. 役に立つ着眼点 • 時間軸の依存関係 – 先に存在すべきオブジェクト – 参照関係 • 発生のタイミング/変化のサイクル – 頻繁で継続的/短い イベント系 – 時々/ゆっくり リソース系 – ほぼ固定 制度 • 「依頼役」と「サービス提供役」 – 「ドメインモデル」はその連鎖 – 大きな責任分界点の見極め(たとえば契約上)
  123. 123. 16章のパターンへのコメント • メタファ – わかりやすいが危険 • 責務のレイヤ – 分析により比較的、論理的に発見できる – データモデリングの考え方と手法が参考になる • 知識レベル – 判断ロジックがごちゃごちゃしたり、置き場所に迷う時 – 簡単な実験 XxxType と Xxx に分けてみる • 従業員タイプと従業員 • 着脱可能なコンポーネントフレームワーク – ここに至るまで熟成している間に環境がかわってしまいそう – 適応型の開発スタイルだと、ここは目的地ではなく、結果
  124. 124. 第17章 戦略をまとめあげる • 「大規模な構造」と「境界づけられたコンテキス ト」を組み合わせる • 「大規模な構造」と「蒸留を組み合わせる」 • まず評価する • 誰が戦略を決定するのか • 戦略的設計の「意思決定」を行うために欠か せない6つのこと
  125. 125. 第17章へのコメント • コードを変更する人間が戦略を理解し、実行に移す ことがもっとも効果的 • このレベルも「言葉」による意思疎通と実験が基本 – 大勢で長期的に取り組む • 変化に対応し、少しずつ成長を続ける全体 – 「適応型」の開発スタイル – このレベルこそ「日々」の変化の積み重ね – 進化を続ける「有機的な秩序」 – 「まちづくりの新しい理論」
  126. 126. 現場での取り組み • A社 システム全体/事業の実情/経営方針を理解する 一人の優秀な技術者が支えている会社 • 契約上は案件ごとのお手伝い • 戦略的設計の実践を意識しながら支援中 • 会社の誕生の時からの長いお付き合い • B社 サービスごとに担当がわかれた小さな技術者集団 • 森を見る意識とスキルの向上の支援 • これも契約上は案件ごとのお手伝い • 昔の部下たち • C社 森を見た「戦略」があり、少しずつ成長する「適応型」 の開発スタイルで活動できる技術部門 • 実戦のための、中核メンバーのさらなる育成とチーム力のアップのお 手伝い(コンサルティング契約)
  127. 127. まとめ
  128. 128. 「ドメイン駆動設計」の理解の鍵 • 「ドメイン」に焦点を当てるとは、具体的にどう いうことか • 「モデル」と「コード」の歩調を合わせるとは、具 体的にどういうことか • 「言葉」を使って、チームで「モデル」と「設計」を 改良するとは、具体的にどういうことか • そのために「オブジェクト指向」と「エクストリー ムプログラミング」の考え方をどう実践するか
  129. 129. 俯瞰 • 第1部 ドメインモデルを機能させる 「ドメインモデル」を中心にすべてを組み立てる 第2部/第3部/第4部に一貫するテーマ • 第2部 モデル駆動設計の構成要素 基本スキル(第3部と第4部の土台) このレベルは「必要」そして「不十分」 • 第3部 より深い洞察へ向かうリファクタリング 実際に「役に立つモデル」を育てる • 第4部 戦略的設計 より広く、より長期的に取り組む
  130. 130. ここに着目して読むと発見が多い • 少しずつ変化し成長していく様子 – 「モデル」/「設計」/「チームが使う言葉」 – 1章、7章、8章、13章、15章、結論、… • 「厳しい状況」の体験談 – 困ったこと – 難しかったこと – 失敗したこと – その時の選択肢と選択の理由 • エクストリームプログラミング/オブジェクト指向の実践例 – 言葉を使った意図の伝達、言葉を使った実験と改良 – 独立性の高い部品(モジュール)の発見と改良
  131. 131. 最後に
  132. 132. • どんな状況でも改善できる • どんなときでも「あなた」から改善を始められる • どんなときでも「今日」から改善を始められる エクストリームプログラミングの 「はじめに」に記された ケント・ベックのメッセージ

×