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

More Related Content

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