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.

3週連続DDDその1 ドメイン駆動設計の基本を理解する

21,247 views

Published on

ドメイン駆動設計の考え方、3原則、基本テクニック
1章から7章

Published in: Technology
  • Be the first to comment

3週連続DDDその1 ドメイン駆動設計の基本を理解する

  1. 1. 第1週 ドメイン駆動設計の基本を理解する 2015年9月2日 増田亨(@masuda220) ギルドワークス株式会社 取締役 有限会社システム設計 代表 3週連続DDD 「ドメイン駆動設計の要点と実践ノウハウ」
  2. 2. 第1週のアジェンダ • ドメイン駆動設計の「考え方」 「まえがき」を中心に • ドメイン駆動設計の「3原則」 1章から3章 • ドメイン駆動設計の「基本スキル」 4章から7章
  3. 3. 第1週の内容を踏まえて • 第2週 「深いモデルの探求」 – モデルと設計の継続的な探求の重要性 – ドメイン駆動設計的なリファクタリング • 第3週 「戦略的に取り組む」 – より広い範囲で長期的に – 誰がやるのか – どうやるのか – いつやるのか
  4. 4. はじめに
  5. 5. そんな人のために この本の要点、考え方とやり方を 実践経験をまじえて そんな人のために この本の要点、考え方とやり方を 実践経験をまじえて ・読み解くのが困難 ・実践でどう活用するか迷っている ・やってみたがうまくいかない
  6. 6. 取り組み • 出会ったのは10年前 –よくわからなかった • 現場で取り組み始めて8年 –7つの開発プロジェクト –3つのコンサルティング
  7. 7. やってみて • 手ごたえ/おもしろさ • 実践の難しさ • たくさんの読み落とし • たくさんの勘違い • 発見と学習と成長
  8. 8. 「ドメイン駆動設計」 の考え方
  9. 9. 「ドメイン駆動設計」とは 厳しい現実の中で、ソフトウェア設計を習得しよ うと奮闘してきた技術者の物語。 不完全な状況の中で、抽象的な設計原則を、 現実のソフトウェアに適用するための助言。 「日本語版への序文」 by エリック・エヴァンス エヴァンスは、ソフトウェア開発の成功も失敗も味わってきた。 この本は、エヴァンスが成功と失敗の両方から学んだ教訓を伝 えている。 「序文」 by マーチン・ファウラー
  10. 10. エヴァンスの取り組み オブジェクト指向 エクストリームプログラミング
  11. 11. エヴァンスの取り組み この二つを組み合わせて、ソフトウェア開発 に取り組んだ。 その成功と失敗の経験から学んだことをまと めたものが「ドメイン駆動設計」。 オブジェクト指向 エクストリームプログラミング
  12. 12. 「ドメイン駆動設計」の想定読者 • 「オブジェクト指向」と「エクストリームプロ グラミング」に、ある程度の知識がある技 術者 • 「オブジェクト指向」と「エクストリームプロ グラミング」の原則を、実際のアプリケー ション開発に適用しようとして、理屈通り にいかないことを経験した技術者 「まえがき」から
  13. 13. オブジェクト指向 エクストリームプログラミング 前提となる知識と経験
  14. 14. オブジェクト指向 エクストリームプログラミング 前提となる知識と経験 私自身は、「ドメイン駆動設計」を初めて読んだ時は、 DOA/手続き型/ウォータフォール系の技術者。 この二つはある程度の知識はあったが未経験。読んでも良くわ からないことがいっぱいあった。 「オブジェクト指向」と「エクストリームプログラミング」を勉強し、 現場でいろいろ挑戦しているうちに「ドメイン駆動設計」の考え 方が理解できるようになってきた。
  15. 15. 勉強になった本 Wabi Sabiを読み解く オブジェクト指向 エクストリームプログラミング 適応型のソフトウェア開発
  16. 16. オブジェクト指向 エクストリームプログラミング 「適応型」のソフトウェア開発
  17. 17. オブジェクト指向 エクストリームプログラミング 「適応型」のソフトウェア開発 2つに共通する考え方は、 成長と変化を続ける 「適応型」のソフトウェア開発
  18. 18. 変化に「適応」する技術 オブジェクト指向の「変更容易性」 エクストリームプログラミングの「変化適応性」
  19. 19. オブジェクト指向の「変更容易性」 エクストリームプログラミングの「変化適応性」 • 「エクストリームプログラミング」は「オブジェクト 指向」のコミュニティで生まれ育った • オブジェクト指向の「変更容易性」が、「適応 型」の開発スタイルをささえている • 相互に補強しあう関係 変化に「適応」する技術
  20. 20. エクストリームプログラミング 「適応型」のソフトウェア開発
  21. 21. 「適応型」のソフトウェア開発 開発の スタイル 方法論 の例 ソフトウェアの 最終形(着地点) 開発サイクル 予測型 ウォータ フォール 事前に厳密に定義 固定 分析/設計/製造 反復・ 漸進型 RUP それなりに定義 反復ごとに精緻化 方向付/推敲/作成/移行 各フェーズで分析/設計/製造を、 N回「反復」する 適応型 XP スクラム YAXP ざっくりと定義 日々更新 日、週、四季 (人間の生活リズム)
  22. 22. 日々、変化し成長する • 毎日、方向付け/推敲/作成/移行を行う。 – 午前は、「方向付け」と「推敲」のためにコードを書く – 午後は、がっつり「作成」する – 夕方、今日の成果を「配置」する – 毎日フィードバックを受け取る • 最終の着地点と進行方向を確認しながら進む – 何か新しいことが起きていないか、毎日、見直す – 進む方向がずれていないか、毎日、見直す – 週で見直し、季節で見直す • 「変化」を知覚したらチームで機敏に対応する – 方向の微調整かもしれない – おおきな方針転換かもしれない – 変えるべき時は大胆に、チーム一丸で
  23. 23. YAXP(もうひとつのXP) • 私がもっとも経験してきた開発スタイル – ラフスケッチ一枚と口頭の依頼 – あいまいでふらつく要求/つかまらない担当者 – 動く画面を見せる度に、追加要求と修正依頼 – 「なるはや」リリース – 人「いない」/予算「ない」 – なんでも自分(たち)でやるしかない • 「ドメイン駆動設計」の良い実践の場
  24. 24. オブジェクト指向の「変更容易性」 エクストリームプログラミングの「変化適応性」 • 「ドメイン駆動設計」の基礎となる設計と開発 の考え方/やり方 • 相互に補強しあう関係 変化に「適応」する技術
  25. 25. オブジェクト指向 「変更容易性」の工夫
  26. 26. オブジェクト指向の「変更容易性」 (どのパラダイムでも同じだけど) • 抽象データ型/段階的な抽象化 – プログラムを人間の発想に近づけると扱いやすい • モジュラープログラミング – 独立性の高い部品に分けると扱いやすい – 関連するデータと操作は、ひとつのプログラミング単位に • メッセージング – 部品の組合せを柔軟に変更できると扱いやすい – sender/receiver/routing – オブジェクト指向言語でうまく実現できていない • Erlang, EIP:Enterprise Integration Patterns, マイクロ サービス, …
  27. 27. LocalDate クラス DateOfBirthのインスタンス変数 日付を汎用的に扱う手段 Java APIのレイヤ int year short month short day LocalDateのインスタンス変数 Java言語仕様のレイヤ if( day > 31 ) … DateOfBirth クラス 「誕生日」に用途を限定した独自定義クラス 「ドメイン層」の一級市民(ドメインオブジェクト) 人間の関心事 コンピュータの 仕組み 抽象データ型/段階的な抽象化 人間の発想に近づける Boolean 今月が誕生月() Days 誕生日まであと何日() plusDays() plusMonths()
  28. 28. OO+XP=ドメイン駆動設計? • 「ドメイン駆動設計」は「オブジェクト指向」と 「エクストリームプログラミング」を組み合わせ た開発の体験談 – エクストリームオブジェクト指向プログラミング • 「ドメイン駆動設計」は、OO+XPの考え方と やり方の「強調」する点をずらしている by エリック・エヴァンス
  29. 29. 「ドメイン駆動設計」が強調する点 • 「ドメイン」に焦点をあてる • 「モデル」と「コード」の歩調を合わせながら、 少しずつ「成長」させる • 「言葉」を使って、チームで「モデル」と「設計」 の「改良」を続ける この三つを組み合わせてソフトウェアを開発した体験 談が「ドメイン駆動設計」の特徴であり魅力。
  30. 30. 「ドメイン駆動設計」の理解の鍵 • 「ドメイン」に焦点を当てるとは、具体的にどう いうことか • 「モデル」と「コード」の歩調を合わせるとは、具 体的にどういうことか • 「言葉」を使って、チームで「モデル」と「設計」を 改良するとは、具体的にどういうことか • そのために「オブジェクト指向」と「エクストリー ムプログラミング」の考え方をどう実践するか
  31. 31. 第1部 ドメインモデルを 機能させる
  32. 32. 「ドメイン駆動設計」の3原則 • 第1章 知識をかみ砕く • 第2章 コミュニケーションと言葉の使用 • 第3章 モデルと実装を結びつける
  33. 33. ドメイン • ソフトウェアウェアを利用する人た ちの「活動」と「関心事」 – ソフトウェアの利用は、活動全体の一部 – 関心事の焦点は、ビジネスや業務上の成果 • ドメインではないこと – ソフトウェアを作る活動 – コンピュータの仕組みや挙動 – 画面仕様書/機能一覧/ユーザーストーリー/…
  34. 34. ドメインとソフトウェア 利用する人たちの 活動と関心事 ソフトウェア
  35. 35. 活動の目的/背景 活動の文脈 ソフトウェア 利用する人たちの 活動と関心事
  36. 36. ドメインのモデリング • 利用する人たちの「活動」と「関心 事」を要約する • 「活動」の要約 –アクティビティ図/業務フロー図 • 「関心事」の要約 –概念モデル図 (クラス図/パッケージ図)
  37. 37. モデル • 膨大な知識を「要約」した シンプルでわかりやすい説明 • モデリングのスキル=「要約力」 –重要な要素を発見する力 –本質的でないものを削る力 –厳密に組み立てる力 ドメイン駆動設計を実践する勘所:「要約力」を磨く
  38. 38. ドメインモデル • ソフトウェアを利用する人たちの「活動」と 「関心事」の本質を簡潔に表したもの • 表現 –チームでかわされる会話 –ラフスケッチ –コード –(文章や図)
  39. 39. 「ドメインモデル」を育てる • 最初は知識が貧弱な浅い「モデル」から • 「ドメイン(利用する人たちの活動や関心事)」 を学びながら、ドメインの知識を広げ「モデル」 に反映する • 重要な点を残し、些細な点を削りとりながら、 「モデル」を深めていく • 「モデル」と「全体」を並行して育てていく – さまざまな要素の入り組んだ関係を、「モデル」を 中核に整理していく
  40. 40. ドメイン駆動設計の基本テーマ • 役に立つドメインモデルを「発見的に成長」さ せていく • ドメインモデルの成長に歩調を合わせて、コー ド設計に「ドメインの知識を反映」していく • モデルをコードで実装してみる実験から、「より 役に立つドメインモデル」の手掛りを得る • 「変化」と「成長」を続ける
  41. 41. 第1部 モデルを活用する 第2章 言葉を使った意図の伝達 第1章 (ドメインの)知識をかみ砕く 第3章 モデルと実装を結びつける モデル ドメイン モデル ドメインの膨大な情報を かみ砕き、蒸留して、 重要な関心事を 鋭く説明する 選び抜かれた ドメインの重要な関心事を コードで表現する 会話を繰り返して モデルを改善する (重要点を明確にする) 会話の中で重要な語彙を 特定する
  42. 42. 第1章 知識をかみ砕く • プリント基板(PCB)設計ツールの開発経験 • (経験から学んだ)効果的なモデリングの要素 • 知識のかみ砕き • 継続的な学習 • 知識豊富な設計 • 深いモデル
  43. 43. 「知識をかみ砕く」体験談 • 「知らない」「わからない」からの出発 • 知識の広げながら「モデル」を成長させる • 「役に立つモデル」の発見 – 「ドメイン」をうまく説明できて、かつ、コードで実装 できる「モデル」を探す • 「深いモデル」の発見と利用 – ソフトウェアを利用する人(PCB設計者)の、ものの 見方と重要な関心事への理解を深める – ドメインを深く理解した知識をコードに反映する
  44. 44. 出発点 図というよりは、頭の中のイメージ ほとんど何もわかっていない
  45. 45. 知識の広がり PCB設計者と会話をしながら 聞き取れる語彙がちょっと増えてきた
  46. 46. ある程度理解できたら 「モデル」が役に立つかコードで実験 だいぶ意思疎通ができるようになってきた段階のモデル PCB設計者の関心事をうまく説明し、かつ、 設計として役に立ちそうか実験
  47. 47. 本質的な関心事にたどり着いた 深いモデル PCB設計者の本質的な関心事をうまく説明しつつ、 ソフトウェアの基本構造としてそのまま使える「深いモデル」
  48. 48. 知識をかみ砕きながら モデルとコードを少しずつ成長させる
  49. 49. 第1章 まとめ • 知識のないところから出発する • 語彙を増やす • ただしい言い方(正しい意味)を覚える • コードで表現してみる • 本質的な関心事を探求する • 継続的に学ぶ • 知識をかみ砕いた成果が「ドメインモデル」 – 利用する人たちの「活動」と「関心事」の本質を簡潔に 表現した言葉・図・コード
  50. 50. 第1部 モデルを活用する 第2章 言葉を使った意図の伝達 第1章 (ドメインの)知識をかみ砕く 第3章 モデルと実装を結びつける モデル ドメイン モデル ドメインの膨大な情報を かみ砕き、蒸留して、 重要な関心事を 鋭く説明する 選び抜かれた ドメインの重要な関心事を コードで表現する 会話を繰り返して モデルを改善する (重要点を明確にする) 会話の中で重要な語彙を 特定する
  51. 51. 第2章 コミュニケーションと言語の使い方 • ユビキタス言語 – 例:貨物輸送プログラム • 声に出してモデリングする • 1つのチームに1つの言語 • ドキュメントと図 • 説明のためのモデル
  52. 52. ユビキタス言語 • いつでも、どこでも、誰とでも – 技術者だけで話あっている時に、「利用する人たちの 関心事」の言葉がでてくれば本物 • 一つ言葉を同じ意味で – 要求仕様や画面に現れる「用語」と、ソフトウェアを利 用する人たちが使う「言葉」の意味の食い違いに注意 • 一つの意味を同じ言葉で – 同じ意味に思える「別の言葉」に敏感に • ユビキタス言語の中で、特に重要な語彙を選び 抜いたものが「ドメインモデル」
  53. 53. 声に出してモデリングする • 良いモデルを見つける実践的な方法 – 語尾まで明瞭に – しゃべりにくい – 耳障りが悪い • 復唱ゲーム – 同じ言葉、同じ言い回しにならない • 他の表現との不一致に敏感に – コード、図、コミットログ、チャット、メールなど書かれた言葉 – 笑っちゃうくらう一致していない • チームのドメインの理解が進み、要点がはっきりしてくる と、よどみなく同じ言い回しがでてくるようになる
  54. 54. 一つのチームに一つの言語 • チーム内では一つ言葉を同じ意味で – 要求仕様や画面に現れる「用語」と、ソフトウェアを利 用する人たちが使う「言葉」の意味の食い違いに注意 • チーム内では、一つの意味は同じ言葉で – 同じ意味に思える「別の言葉」に敏感に • 第4部の「境界づけられたコンテキスト」や「継続 的な統合」の基本原理 • エクストリームプログラミングでは、ドキュメントの 代わりに「会話」をする
  55. 55. 言葉たいせつ • 「エクストリームプログラミング」では、言葉を 使った会話がドキュメントの代わり – 意図伝達の主要な手段 • 「言葉」は、そのままクラス/メソッド/パッ ケージの候補 • あらゆる場所で同じ言葉を – 会話/チャット/メール/コミットログ/ソースコード
  56. 56. 言葉たいせつ •開発者が、利用者の「重要 な関心事」をよどみなく語り 始める安心感 •開発者が、技術用語しか 使わない恐怖感
  57. 57. 第1部 モデルを活用する 第2章 言葉を使った意図の伝達 第1章 (ドメインの)知識をかみ砕く 第3章 モデルと実装を結びつける モデル ドメイン モデル ドメインの膨大な情報を かみ砕き、蒸留して、 重要な関心事を 鋭く説明する 選び抜かれた ドメインの重要な関心事を コードで表現する 会話を繰り返して モデルを改善する (重要点を明確にする) 会話の中で重要な語彙を 特定する
  58. 58. 第3章 モデルと実装を結びつける • モデル駆動設計 • モデリングパラダイムとツールによるサポート • 骨格を見せる:なぜモデルがユーザにとって重 要なのか? • 実践的モデラ
  59. 59. モデル駆動設計 ドメイン駆動設計が必要とするモデル • 初期の分析を支援するだけでなく、設計にお いて土台になるモデル • 両方に役に立つモデルを探す – 簡単には見つからない – 最初からは見つからない – 少しずつ実験し、学習し、良いモデルに育てていく – 言葉による実験/コードによる実験
  60. 60. モデリングパラダイムと使用言語 • オブジェクト指向は、モデリングと実装を一致させること が、考え方の基本にある – 分析クラス=実装クラス – しかし、理屈通りにはなかなかうまくいかない – そこで「ドメイン駆動設計」 • 手続き型プログラミングは、コンピュータを使ったデータ 操作モデルになりがち – 基本データ型と、その操作命令だけのコード – 人間の考え方に近づける段階的な抽象化の不足 • 「述語論理」と「論理型」プログラミングは一致している – 広くは採用されていない
  61. 61. (ドメイン層の)骨格を見せる なぜモデルがユーザにとって重要か? • 「モデル」が、利用者の「重要な関心事」を反映 していれば、主要なクラスとその関係は、利用 者にとって理解できる • ソフトウェアとして表現された「モデル」から、 利用者はソフトウェアの潜在的な可能性に触 れることができる • とんでもない勘違いを発見できる • オブジェクトの構造を画面レイアウトや画面遷 移的に説明すると、会話しやすい
  62. 62. 実践的モデラ • コードを書かない人間が、利用者の 活動や関心事を深く理解しても、良 いソフトウェアは生まれない • コードを書く人間が、ドメインの知識 をかみ砕き、重要な関心事を正しく 理解するのが、もっとも確実で、もっ とも効果的なソフトウェア開発手法
  63. 63. 第2部 モデル駆動設計の 構成要素
  64. 64. 第2部 モデル駆動設計の構成要素 • 第4章 ドメインを隔離する • 第5章 ソフトウェアで表現されたモデル • 第6章 ドメインオブジェクトのライフサイクル • 第7章 言語を使用する:応用例
  65. 65. 第2部 モデルと実装の一致 • モデルと実装の一致は非常に難しい • 何をすべきか – ドメインの隔離 – モデルをコードで表現する – ドメインオブジェクトのライフサイクル – モデル駆動設計のやり方(進め方)
  66. 66. 第2部は基礎練習 • ボールを蹴って止める基本の練習 • 相手に囲まれても確実にできる • 90分走りぬいたあとでも確実できる • ぬかるんだピッチでも確実にできる • 第2部の構成要素をどんな状況でも、確実に 使えることが、「第3部 深いモデル」、「第4部 戦略的設計」を実践する土台になる。
  67. 67. 第4章 ドメインを隔離する • レイヤ化アーキテクチャ • ドメイン層は「モデル」が息づく場所 • 利口なUI(アンチパターン) • その他の隔離
  68. 68. レイヤ化アーキテクチャ
  69. 69. ドメインの「隔離」 • ドメイン層を分離 – 表面的な分離は簡単 • 現実 – コントローラ層やページ記述にしみだした業務知識 • if(未承認なら) setDisable() – 複雑なSQL文にまぎれこんだ業務知識 • NOT EXIST xxx OR customer.type = 1 • 業務知識のまぎれこみに敏感になる – アンチパターンを覚える • 継続的にリファクタリングする – 画面が動くと、あらたなビジネスルールが発見され、それをコント ロールや画面で処理するアンチパターンが横行する • データベースのフラグと区分はアンチパターンの宝庫
  70. 70. ドメイン層 • 「モデル」を表現するのはドメイン層のコードの 一部 – 「重要な関心事」のコードのまわりに、その他の関 心事のコードが集まってくる • ドメイン層にドメインの知識を集め続ける – コードが知識豊富になり、深いモデルの発見の可 能性が広がる – 画面やSQLに書き加えられがちな、ビジネス知識を 丹念に、継続的に、ドメイン層に移動する
  71. 71. ドメイン層にロジックを集める工夫 • 2ステップビュー • 操作モデルとボタン表示 • 動的SQLの記述 …
  72. 72. 2ステップビュー • ドメイン層とプレゼンテーション層の関係 • Step1:ドメインオブジェクトが論理構造を返す – 例えば、List<String> • プレゼンテーション層のヘルパークラスが、論 理構造を物理構造に変換する – 例えば、 <tr> </tr>
  73. 73. 操作モデルとボタン表示 • 状態による操作の違い • ActionList オブジェクトをプレゼンテーション 層に渡す • その情報を元にプレンゼンテーション層が、ボ タンを出し入れする
  74. 74. 動的SQLの記述 • ドメインオブジェクトに論理構造を持たせる – 動的な AND/OR 条件 – 動的な ORDER BY 句 • データアクセス層のヘルパークラスが、ドメイン オブジェクトが返す論理構造をSQLにマッピン グする
  75. 75. 第4章のまとめ • ドメインを隔離する • 形式的なコーディングルールや、フレームワークの 導入だけでは、隔離できない • プレゼンテーション層からドメインロジックを抽出し てドメイン層に移動し続ける • データソース層からドメインロジックを抽出してドメ イン層に移動し続ける • ちょっとした修正で、ドメインの知識がドメイン層 以外に拡散する危険を察知する嗅覚を磨く
  76. 76. 第5章 「モデル」をプログラムで表現する • 関連 • エンティティ • 値オブジェクト • サービス • モジュール • モデリングパラダイム
  77. 77. 第5章の問題意識 • モデルとコードの一致は難しい • 「モデル」は、人間の関心事の要約 – 「自然言語」で表現する(意図を伝達する) • プログラミング言語という人工言語で、どう、人間 の関心事を表現するか? – 細かい点に気を配らないと、すぐにモデルと実装が離 れていく – モデル(重要な関心事)と実装が分離すると、ソフト ウェアが的はずれなものになったり、変更がたいへん になる – ソフトウェアの成長が止まる
  78. 78. モデルをコードで表現する工夫 • スリムな「エンティティ」 • 部品の独立性を高める「値オブジェクト」 • 操作の自然な置き場所を見つける「サービス」 • 重要な関心事「ファーストクラスコレクション」 • ビジネスルールの表現手段「区分オブジェクト」
  79. 79. ドメイン駆動設計
  80. 80. 何が違うのか? 「関連」を考えなくて良い 「集約(Aggregates)」を考えなくて良い データベースとマッピングしやすい 「関心事」があいまい(ごった煮) 「関連」の設計と実装が必要 「集約」の設計が必要 データベースとのマッピングが複雑 「関心事」を発見してクラスに抽出
  81. 81. 成長を続ける「適応型」アプローチ • ドメインを学びながら「関心事」を発 見する • 「関心事」をクラスに「抽出」しなが ら、モデルとコードの両方を育てる • ドメインの「関心事」を、さらに深 掘っていくとっかかり – 住所がない場合? – 複数の住所? – 住所がわかる時/変わる時
  82. 82. ドメイン駆動設計のやり方 ボールを蹴って止める基礎技術
  83. 83. 値オブジェクト(Value Objects) • 大きなクラスの「分割」ではなく、重要な「関心事」 を発見し「抽出」する感覚 • メソッドを「知識豊か」にする手段 – 引数の型/メソッドの返す値の型 × long を渡して String を返す ◎ 「顧客ID」を渡して「住所」を返す • 人間の関心事に近づける努力 – int,String,LocalDateだけでは、ドメインの「関心 事」を具体的に表現できない – 「顧客」や「住所」など、関心事を表現する独自の「型」 を定義する • 抽象データ型/段階的な抽象化
  84. 84. エンティティ(Entity) • 太りがち – インスタンス変数 – ロジック ⇒概念が暗黙知になりがち • とことんスリムにする – 「識別」という利用者の関心事に集中する • 一覧の表示順や検索項目 • 特に関心があることの発見 – 「内容を説明」する関心事は「値オブジェクト」にま かせる(別の議論にする)
  85. 85. ドメイン層のサービス • どの「エンティティ」や「値オブジェクト」に置くべ きか迷うロジックがいろいろでてくてる • そういう時は、そのロジックに名前を付けてク ラスとして抽出してみる(実験) – XxxPolicy – XxxRule – XxxProcedure …
  86. 86. ドメイン層のサービス 危険! • 「手続き」にドメインの「関心事」が隠ぺいされがち – 深いモデルの探求の手掛りを見失う • 同じ「ロジック」が複数サービスに重複しがち – 変更コストがあがる – モデルとコードの成長の障害になる • 考え方とやり方 – メソッドの引数と型は「ドメインオブジェクト」にする • long や Stringを使わない – 基本は多態(ルールの場合ごとの切り替え)の道具 – それ以外の場合、リファクタリングの候補としておく • より適切な置き場所を模索することで、良いモデルを探求
  87. 87. その他の有用な構成要素 • ファーストクラスコレクション • 区分オブジェクト
  88. 88. ファーストクラスコレクション • コレクションをラップしたドメインオブジェクト • Products • PurchaseHistory • 「一覧」や「履歴」を表現したオブジェクト – 一覧画面などに対応するドメインオブジェクト – 「一覧」に関する利用者の関心事のモデル • SQL文の複雑な問合せでがんばる? – SQLの抽出条件は単純にして、微妙な抽出や問合せ を、オブジェクトにやらせる、というのも選択肢 – どちらが、ドメインの概念をうまく表現するか – 変更があった時に、どちらが楽で安全か
  89. 89. 区分オブジェクト • 振る舞いを持った Enum • 区分ごとのロジックを別クラスに記述 • Java言語使用に組み込まれた Strategy/Stateパターン 説明とコード例は、googleで 「場合わけの書き方あれこれ」で検索。 または「ソフトウェアデザイン9月号」 場合ごとのルールを理解し表現する工夫
  90. 90. モジュール(Packages) • 重要なモデリング要素 – 関連するドメインオブジェクト(の型)のグループ – 利用者の関心事の「境界」を表現する手段 – プログラミング単位 – テスト単位 • 「適応型」のアプローチの対象 – 新しい発見とともに、積極的にパッケージ名/ パッケージ構成を変更し育てていくこと • 「第4部 戦略的設計」の主要ツール
  91. 91. モデリングパラダイム • このテーマが「第5章 ソフトウェアで表現された モデル」に登場する意味 – 「モデリングの考え方」と「実装の考え方」 – 基本が同じであれば、モデルをコードで表現しやすい – 分析クラス=実装クラス • 「モデル」と「実装」の歩調を合わせて育てていく これがやりやすいパラダイムは? – モデリングの原則と実装の原則の歩調を合わせやす い – モデリングの実践スタイルと実装の実践スタイルの歩 調を合わせやすい – モデルの変更と実装の変更の歩調を合わせやすい
  92. 92. オブジェクトパラダイム • エヴァンスが取り組んだこと(この本はその体験談) • オブジェクトの世界におけるオブジェクトではないもの – 述語論理(AND/OR/NOT/EXIST) – 複雑な数学計算 – 関係データベース • パラダイムを混在させる際にはモデル駆動設計に忠実 であること – 実装パラダイムと対立しない(違いを正しく理解する) – ユビキタス言語を使って統合性を保つ – UMLにこだわらない – パラダイムの混在は懐疑的に(メリットよりデメリットを重く)
  93. 93. 第5章のまとめ • ソフトウエアで表現したモデル • 「モデル」と「実装」の一致は難しい • そのための基本スキルを体で覚える • 丁寧に地道に続ける • 第3部、第4部の土台 – ほんとうに役に立つのは深いモデルを見つけた時 – 大きな効果がでるのは戦略的に取り組んだ時
  94. 94. 第6章 ドメインオブジェクトのライフサイクル • 集約 • ファクトリ • リポジトリ
  95. 95. 第6章の問題意識と解決の工夫 • 複雑になりがちな箇所 – オブジェクトのライフサイクル管理 • 生成/格納・再構成/修正/削除 – オブジェクト間の整合性の管理 • 「モデル」をこの複雑さから守るために – ドメインオブジェクトのネットワーク構造と「集約」 – オブジェクトの生成と「ファクトリ」 – 必要なオブジェクトを簡単に入手する「リポジトリ」
  96. 96. 「集約」 • ドメインオブジェクトのネットワーク構造 – 利用者の「活動」や「関心事」の結びつきを反映す るので、必然的に複雑になる • 「集約」という単位を導入して、複雑なネット ワークに「構造」を導入する(設計上の問題) – 「ひとかたまり」として扱うべき境界を探す – 言語仕様上に表現手段がないのが難点
  97. 97. 「ファクトリ」 • オブジェクト(の集約)の生成 – エンティティ(集約のルート)が自分で持つと、エンティ ティ本来の関心事があいまいになる – 「コード」が複雑になり「モデル」との対応があいまいに なる • 生成ロジックの置き場所 – 「集約のルート」のファクトリメソッド – 「集約の生成」に関わるオブジェクトのファクトリメソッド – コンストラクタ – 独立したファクトリクラス …
  98. 98. 「リポジトリ」 • 必要なオブジェクトの集約を入手する • あたかもすべてのドメインオブジェクトがメモリ 上にあるように設計する – データベース設計やORマッピングをいったん忘れる – interface 宣言で実装を分離する • やりたいことをシンプルに宣言する • 注文 findBy(管理番号) • 注文一覧 lookFor(検索条件) • void register(注文)
  99. 99. 第6章の補足(実践例) • 注文Repository#prototype() – データベースのシーケンスを使った管理番号を持ったド メインオブジェクトの生成 – 注文受付番号を持ったドメインオブジェクトを返す – 入力画面に渡す – デフォルト値の設定 • 「トランスファ」インタフェース – 「通知」を表現するモデル要素 – 「記録・参照」を表現した「リポジトリ」と似ている – 実現手段は、データアクセス層で実装する
  100. 100. 第7章 言語を使用する:応用例 • 4章、5章、6章の「構成要素」を組み合わせ る実戦に近い練習 • 仮想的なチームが要求と実装の問題に対処し ながら「モデル駆動設計」で開発をしていく例 • その過程で生じる「さまざまな問題」と「どう解 決」されるかを見ていく • 読み取るのはたいへんだが、発見と学びが多 い章
  101. 101. 第7章の構成(流れ) 1. 貨物輸送システムの概要 2. ドメインを隔離する:アプリケーション層の導入 3. エンティティと値オブジェクトを区別する 4. 輸送ドメインの「関連」を設計する 5. 「集約」の境界 6. 「リポジトリ」を選択する 7. シナリオをウォークスルーする 8. オブジェクトの生成 9. リファクタリングのために立ち止まる 10.輸送モデルにおける「モジュール」 11.新機能を導入する:配分チェック 12.最後に
  102. 102. 第7章はより実戦に近い練習 • 「モデル」と「実装」が育っていく過程とリズム • 「モデル駆動」で設計するということ – まず「アプリケーション層」を導入する • 「ドメイン層」の議論を「機能」視点から隔離する • 機能(処理)の詳細化からの設計ではない – 入出力項目(画面帳票)の定義は登場しない • プレゼンテーション層無しのドメイン層の設計と実装 – データモデル/テーブル設計は登場しない • データモデルから独立したドメイン層の設計と実装
  103. 103. 関連・集約・リポジトリ • 第7章の議論のハイライト • 「関連」を設計する – 関連の方向の議論はドメインに対する洞察 – 複雑な実装を避ける(成長容易性の確保) • 「集約」の境界 – ドメインオブジェクトの「かたまり」の定義 – 概念(関心事)の境界の明確化 – 開発単位 • 「リポジトリ」を選択する – 機能視点が登場するタイミング • 検索/選択/登録 …
  104. 104. 3週連続 DDD 第1週のまとめ
  105. 105. ドメイン駆動設計 • エクストリームオブジェクト指向プログラミング • 少しずつソフトウェアを成長させる「適応型」の 開発スタイル オブジェクト指向 エクストリームプログラミング
  106. 106. 「ドメイン駆動設計」が強調する点 • 「ドメイン」に焦点をあてる • 「モデル」と「コード」の歩調を合わせながら、 少しずつ「成長」させる • 「言葉」を使って、チームで「モデル」と「設計」 の「改良」を続ける この三つを組み合わせてソフトウェアを開発した体験 談が「ドメイン駆動設計」の特徴であり魅力。
  107. 107. 「ドメイン駆動設計」の理解の鍵 • 「ドメイン」に焦点を当てるとは、具体的にどう いうことか • 「モデル」と「コード」の歩調を合わせるとは、具 体的にどういうことか • 「言葉」を使って、チームで「モデル」と「設計」を 改良するとは、具体的にどういうことか • そのために「オブジェクト指向」と「エクストリー ムプログラミング」の考え方をどう実践するか
  108. 108. ドメインモデルを活用する 第2章 言葉を使った意図の伝達 第1章 (ドメインの)知識をかみ砕く 第3章 モデルと実装を結びつける モデル ドメイン モデル ドメインの膨大な情報を かみ砕き、蒸留して、 重要な関心事を 鋭く説明する 選び抜かれた ドメインの重要な関心事を コードで表現する 会話を繰り返して モデルを改善する (重要点を明確にする) 会話の中で重要な語彙を 特定する
  109. 109. モデルと実装を一致させ続ける • モデルと実装の一致は非常に難しい • やるべきこと – ドメインを隔離し続ける – モデルを的確にコードで表現する工夫を続ける – ドメインオブジェクトの複雑化を防ぎ続ける • 発見と学習と成長を続ける – ドメインの知識 – 深いモデル – 実装に役立つモデル
  110. 110. ボールを蹴って止める練習 • スリムな「エンティティ」 • 部品の独立性を高める「値オブジェクト」 • 操作の自然な置き場所を見つける「サービス」 • 重要な関心事「ファーストクラスコレクション」 • ビジネスルールの表現手段「区分オブジェクト」 • オブジェクトのネットワーク構造に切り込む「集約」 • 生成を切り離して扱う「ファクトリ」 • 全てはメモリ上にあるかのように「リポジトリ」
  111. 111. 第1週の内容を踏まえて • 第2週 「深いモデルの探求」 – モデルと設計の継続的な探求の重要性 – ドメイン駆動設計的なリファクタリング • 第3週 「戦略的に取り組む」 – より広い範囲で長期的に – 誰がやるのか – どうやるのか – いつやるのか
  112. 112. 最後に
  113. 113. • どんな状況でも改善できる • どんなときでも「あなた」から改善を始められる • どんなときでも「今日」から改善を始められる エクストリームプログラミングの 「はじめに」に記された ケント・ベックのメッセージ

×