qcon tokyo 2013

37
小さなオブジェクトで ドメインモデルを組み立てる Qcon Tokyo 2013 2013年4月23日 有限会社 システム設計 増田 ドメイン駆動設計 実践ガイド

Upload: -

Post on 27-Jun-2015

2.704 views

Category:

Technology


0 download

DESCRIPTION

ドメイン駆動設計の実践ガイド

TRANSCRIPT

Page 1: QCon Tokyo 2013

小さなオブジェクトで ドメインモデルを組み立てる

Qcon Tokyo 2013

2013年4月23日

有限会社 システム設計 増田

ドメイン駆動設計 実践ガイド

Page 2: QCon Tokyo 2013

Domain-Driven Design (DDD)

ドメイン駆動設計

Page 3: QCon Tokyo 2013

コンセプト編 1. 業務アプリケーション 2. 開発の難しさ 3. ドメイン駆動設計のアプローチ

Page 4: QCon Tokyo 2013

業務アプリケーション • データの種類と量

• ユーザの役割と権限

• 履歴データ:記録、参照、照合、…

• 通知・連絡・報告とルーティング

• 予定(未来)の管理

• 状態遷移

• 状態+権限に依存した制約ルール

• 人間の判断待ち

Page 5: QCon Tokyo 2013

開発の難しさ • 複雑さ

– 権限、状態、区分、… 組み合わせ – 例外規定、救済ルール

• あいまいさ – ビジネス=人と人との相互作用 – 決め事・調整ごとの積み重ね – 暗黙の前提

• 不確実性 – ビジネス環境の変化 – 事業の変化 – 人の異動、組織の変更

Page 6: QCon Tokyo 2013

• 複雑さに立ち向かう

• あいまいさに光をあてる

• 不確実性を受け入れる

ドメイン駆動設計

Page 7: QCon Tokyo 2013

アプローチ • 「概念モデル」をそのまま実装

• ドメイン層の独立

• モデルの継続的な改良

Page 8: QCon Tokyo 2013

概念モデルをそのまま実装 • 名前

– パッケージ名、クラス名、メソッド名、…

– 業務用語に合わせる (粒度、関連性)

• 業務の構造に合わせる – 業務手順

– サービスポリシー、キャンセルポリシー、…

– 会計ルール、管理会計、評価基準、…

• 現実主義 – 実装の都合・制約からのフィードバック

– 設計判断

Page 9: QCon Tokyo 2013

ドメイン層の独立 • 関心事の分離

– 業務の関心事と実装の関心事

– UI、データベース、通信

• 依存関係の逆転 – 他の層がドメイン層に依存

• DIP : Dependency Inversion Principle

– 例:永続化(データベースアクセス) • ドメイン層でインタフェース宣言:業務のやりたいこと

• データアクセス層で実装:実装技術依存コード

Page 10: QCon Tokyo 2013

ドメイン層の継続的改良 • モデルの深化

– ドメインの理解度の深まりを継続的に実装に反映

– 機能追加やバグ修正が、ひとつのチャンス

• モデルの変化

– ビジネスモデルの変化を反映し続ける

• コミットログ(変更理由)は業務の言葉で

– 不要・無効になった概念・ルールを丁寧に除去

Page 11: QCon Tokyo 2013

実践編 4. アプリケーション・アーキテクチャ 5. ドメイン層の設計パターン 6. リッチなドメインモデル 設計スタイル

お断り:Java/Spring フレームワークでの実践例です。

Page 12: QCon Tokyo 2013

アプリケーション アーキテクチャ

Page 13: QCon Tokyo 2013

構築モデル

アプリケーションサーバー

アプリケーション フレームワーク

アプリケーション ロジック

アプリケーションコンテナ ディスパッチャ イベントリスナー

Web MVC バリデーション O-Rマッピング テンプレートエンジン

独自に開発

再利用

再利用

@Autowired

Page 14: QCon Tokyo 2013

ドメインモデル

イベント駆動の実行モデル

ブラウザ, Web API

HTTP リクエスト

メール

受信メール自動処理

非同期 メッセージ

サービス間連携

アプリケーションサーバー Tomcat

メッセージング Active MQ

サービスコンテナ Mule ESB

メールサーバーJames

Mailet コンテナ

Servlet コンテナ

サービス

業務イベント

ユースケースの実装

業務知識 ビジネスルール

マクロな業務手順 (トランザクションスクリプト)

問題領域の オブジェクトモデル

サービス起動トリガー

Page 15: QCon Tokyo 2013

リッチな ドメインモデル

シンプルな ドメインモデル

ドメイン層の2つの

実装スタイル

手続き型 記述

オブジェクト モデル

リッチな トランザクション

スクリプト

シンプルな トランザクション

スクリプト

大きい(たくさんのインスタンス変数) データの入れ物(getter/setter) テーブルと対応 小さい(1つ2つのインスタンス変数)

データ+ロジック テーブルのカラム

Page 16: QCon Tokyo 2013

設計パターン リッチなドメインモデル

日付

期間

予定日

有効期限

場所

地域

商品種類

形状

単価

数量

税率 型式

翌月 拠点

キャンペーン

Event (出来事)

シンプルなトランザクションスクリプト

Reference (参照/追跡)

Repository (記録)

Transfer (通知)

Policy (判断) (制約)

部門

役割

担当者

ファンダメンタルなオブジェクト

端数

超重要

ここが 育つほど 楽になる

ユースケースの実装

基本 オブジェクト

Page 17: QCon Tokyo 2013

ドメイン層の基本オブジェクト

Event (出来事)

Service (業務機能)

Reference (参照/追跡)

Repository (記録)

Transfer (通知)

Policy (判断/制約)

トランザクションスクリプト ファサード(実際の仕事はドメインオブジェクトに任せる)

問題領域の出来事を表すオブジェクト イベント種別、いつ/だれが/何を

記録と参照の業務ニーズの表現 インタフェース宣言(実装は、データソース層で)

通知の業務ニーズの表現 インタフェース宣言(実装は、データソース層で)

関心事の「識別」(参照番号、管理番号、追跡番号、…) 関連オブジェクトの集約ルート(値オブジェクトの集約)

ルールの集約 (プライシング、キャンセル、オーバーブッキング、…)

Page 18: QCon Tokyo 2013

ファンダメンタルなオブジェクト リッチなドメインモデルの構築基盤

日付

期間

予定日

有効期限

場所

地域

商品種類

形状

単価

数量

税率 型式

翌月 拠点

キャンペーン

部門

役割

担当者

• 業務モデルを表現する基本語彙集 • ビジネスルールの基本ロジック 日付計算、形式チェック、区分の列挙、… • プログラミング言語のプリミティブな型のラッパー

端数

Page 19: QCon Tokyo 2013

役に立つ ドメインオブジェクト

良い名前

小さく

ばらばらに

Page 20: QCon Tokyo 2013

良い名前の見つけ方

正しく使う(言葉を使って相手の反応をみる)

言葉を組み合わせてみて反応をみる

似た言葉を使い分けて反応をみる

名前の宝庫(初日に見つける) ・その分野のガイドブック ・類似サービスのヘルプ画面 ・類似パッケージソフトのカタログ (英語版ならクラス名の宝庫)

頻度、重要度、関心度、…

語彙を増やす 読む/調べる 聴く/尋ねる

Page 21: QCon Tokyo 2013

小さく作る クラス 50行以内 メソッド 3行以内 パッケージ 10ファイル以内

これを超えたら、 分割を考える習慣をつける。

Page 22: QCon Tokyo 2013

3行メソッド

register( order ) { verify( order ); record( order ); notifyTo(shippingSection); }

こういうのが良い感じ

Page 23: QCon Tokyo 2013

小さく作る狙い

作りやすい わかりやすい 使いやすい 捨てやすい

Page 24: QCon Tokyo 2013

業務の言葉をオブジェクトで

プログラミング言語の基本データ型 (Date,String, BigDecimal, Long, …)

をラップした 業務の基本用語ごとのオブジェクトに、

その用語に関するデータとロジックをまとめる。

日付 (時分秒を持たない) 時分(秒を持たない) 翌営業日, 休前日 月末,月初, 四半期, 半期, 年度 期間 有効期限 予定日 期限切れ一週間前のアラート 前日のリマインダ …

金額 単価 数量,数量単位,換算 消費税,税率,端数処理 合計,小計,総合計 数量割引 キャンペーン価格 季節料金 キャンセルポリシー …

管理番号,登録番号 取引先コード 取引区分 契約番号 商品番号 型式コード 製造番号 シリアルナンバー …

用語の粒度=オブジェクトの粒度

Page 25: QCon Tokyo 2013

委譲メソッド 面倒でも隣人とだけ話す × person.contactInfo().phones().mobile() ◎ person.primaryContact()

ばらばらにする習慣

実装継承 控え目に。もっと控えめに。

パッケージ階層 フラットに。もっとフラットに。

• 構造を安易にコードに埋め込まない。 • 初期の構造はまちがっていることが多い。 • 構造の変更を簡単にする準備をしておく。

構造の変更に備える

Page 26: QCon Tokyo 2013

ビジネスロジックの カプセル化

• if 文/switch 文を使わない

• for 文を閉じ込める/使わない

Page 27: QCon Tokyo 2013

if 文 / switch 文を使わない

• 列挙型(enum)

–区分、種別、カテゴリー、エリア、… – EventType, StateType, Category, …

– タイプごとの振る舞いを if 文なしに記述

• Strategy/State パターン • たとえば、「未記入」や「不明」の表現→ MissingObject パターン

• Map, Set

Page 28: QCon Tokyo 2013

for文を閉じ込める/書かない • ファーストクラスコレクション

– コレクション変数は単独でラッピング

• List<Order> orders ; → class Orders

– for 文を使ったロジックの集約と整理

• コレクション操作の副作用の撲滅

• for 文を書かない – コレクション API の活用

– Comparable/Comparator の実装

– equals()/hashCode() のオーバーライド

Page 29: QCon Tokyo 2013

ドメインオブジェクトの

組み立て方 • サービスクラスを起点に

– サービスクラスはマクロな業務手順(数行)を記述 – 判断・分岐・導出は、ドメインオブジェクトに委譲

• フレームワーク(Inversion of Control) – 組み込み済の制御構造

• Web MVC、 バインド&バリデーション • O-R マッピング、 O-X マッピング • 例外ハンドラー

– @Autowired • パターンマッチング、命名規約、アノテーションで自動で組み

立ててくれる。

Page 30: QCon Tokyo 2013

参考情報 7. 設計と実装のスキルアップ 8. ドメインモデルの開発スタイル 9. 問題領域の把握手法 10. 開発プロセス

Page 31: QCon Tokyo 2013

設計と実装のスキルアップ

エクササイズ 9つのルール 小さく作る

・メソッドの構成 ・オブジェクト間の特性移動 ・データの再編成 ・条件記述の単純化 ・メソッド呼び出しの単純化

実装の原則

ドメインの理解 言葉の力 モデル駆動

設計のスタイル

For Thoughtful Developer Leading Designer

オブジェクト指向

基礎訓練

・クラス ・振る舞いとメソッド ・状態とコレクション

設計の改善

責任割当の原則 GRASP

責任駆動設計 役割ステレオタイプ

契約による設計

Page 32: QCon Tokyo 2013

リファクタリング

モデリング プログラミング

イテレーティブで発見的な活動

ドメインモデルの開発

三位一体

Page 33: QCon Tokyo 2013

リレーションシップ駆動 要件定義(RDRA)

・コンテキストモデル ・業務フローモデル ・イベント/状態モデル

ICONIX

・ドメインオブジェクトの発見 ・ドメインモデルの育て方 ・ロバストネス分析

ビジネスルールの発見と定義

業務フロー図から ドメインモデルから イベント/状態モデルから

問題領域を把握する

初期のラフモデルを 2時間以内で描く

モデル間を関連づけ 整合性と網羅性を確保

ユースケースと 実装のギャップを埋める

それぞれのモデルから ビジネスルールを抽出する ヒントとテクニック

Page 34: QCon Tokyo 2013

ドメイン駆動の開発プロセス

業務フロー

モデルの改良

要約、骨格

画面・帳表 ユースケース

属性の追加 モデルの洗練

イベント 状態遷移

データモデル

初期の ラフモデル

コンテキスト図

手がかかり

初日からドメインモデルの設計と実装

ロバストネス分析

必要ならシーケンス図

操作追加

Java ソース

基盤クラス追加

DDL/SQLソース

問題領域の把握

構造化用語集

Page 35: QCon Tokyo 2013

Domain-Driven Design (DDD)

ドメイン駆動設計

まとめ

Page 36: QCon Tokyo 2013

アプローチ • 「概念モデル」をそのまま実装

• ドメイン層の独立

• ドメインモデルの継続的な改良

Page 37: QCon Tokyo 2013

役に立つ ドメインオブジェクト

良い名前

小さく

ばらばらに