Submit Search
ドメイン駆動設計入門
•
112 likes
•
28,755 views
増田 亨
Follow
BPStudy #73 発表資料。
Read less
Read more
1 of 53
Download now
Downloaded 237 times
More Related Content
ドメイン駆動設計入門
1.
ドメイン駆動設計入門 2013年9月26日 有限会社システム設計 増田 BPStudy #73
2.
1.ソフトウェアの核心ドメインモデル 2.ドメインモデルとオブジェクト指向 3.ドメイン駆動設計のインプット 4.ドメインモデルの実装パターン アジェンダ
3.
1 ソフトウェアの核心 ドメインモデル
4.
業務システムの基本構成 画面 アプリケーション 連携 アプリケーション 帳票 アプリケーション データベース
5.
ドメインモデルパターン 画面 アプリケーション 連携 アプリケーション 帳票 アプリケーション データベース ドメイン モデル (ビジネス層) 業務の データとロジック
6.
ドメインモデル • 業務のデータと業務の機能をコードで表現 – ビジネス層に集約する –
関係するデータと機能をクラスにまとめる • ハイブリットなアプローチ – データの視点と機能の視点 • 両方からアプローチする • 二つの視点をいったりきたりする – データと機能の結びつき強める • クラスにカプセル化 • データ保持クラスと機能クラス(データ操作クラス) に分けるのはアンチパターン
7.
関連するデータと機能は クラスにまとめる 氏名 nameKana() originalFamilyName() 住所 line() city() 連絡 手段 firstChoice() change() changePriority() 連絡 履歴 unprocessed() lastThreeContacts() withinTwoMonths()
8.
ドメインモデルをみんなで使う 画面 アプリケーション 連携/バッチ アプリケーション 帳票 アプリケーション データベース 氏名 住所 連絡 履歴 連絡 手段 業務で使う データ+ロジックを ここに集約
9.
作る順番 データベース OR マッピング 2 5 アプリケーション サービス (API宣言) 3 ドメイン モデル 1 機能テスト 4
10.
なぜ ドメインモデル パターン で作るのか?
11.
コード量が減る
12.
• テストが減る • ドキュメントが減る •
バグ調査が楽になる • 変更の影響が見通しやすい コード量が減れば
13.
ドメインモデルは コードの重複を減らす • あちこちに分散しがちな業務ロジックを データ中心に整理し、集約する • いやな臭い –
データを要求する getter メソッド • そのデータを使うロジックが、別のクラスに分散 • あちこちのクラスに重複して書かれている危険な 兆候
14.
コードが膨張するアンチパターン • トランザクションスクリプト – 機能単位/画面イベント単位に業務ロジックを記述 –
あちこちの画面/帳票/外部連携に、似たロジック が繰り返し登場 – 使われない「共通業務ロジック」(共通部品構想の 残骸) • どこでも業務ロジック – ビュー記述に業務ロジックをべた書き – 画面コントローラに業務ロジックをべた書き – Data Access Object に業務ロジックをべた書き – SQL に業務ロジックをべた書き
15.
ドメインモデルに 業務ロジックを集めて 重複したコードを 減らしましょう
16.
アプリケーションの中核部品 画面 アプリケーション 連携 アプリケーション 帳票 アプリケーション データベース ドメイン モデル ここに 業務ロジックを 集める
17.
ドメインモデル 表面に見えるメリット • コード量が減る • 業務のロジックが書いてある場所が見つ けやすい •
業務のロジックを変更した時の影響範囲 が局所化される
18.
ドメインモデル ほんとうの価値 • 業務の知識の浸透 – ビジネス目標/システムの価値の理解 –
業務の全体像/基本の仕組みの理解 – 業務の現場にある肌感覚、現場の知恵 • 言語表現を超えた暗黙知が育つ – 業務アプリケーションの設計のコツ、かんどころ、 おとしどころ、… – 個人に内面化された価値観、方向感 – チームで共有化された価値観、方向感 • 「あたり」がつくようになる – 的外れの作業/とんでもない勘違い/手戻りが減る – 進むべき方向がわかりやすくなる
19.
2 ドメインモデルと オブジェクト指向設計
20.
個人的な話 • ドメイン駆動設計に出会って、オブジェ クト指向も便利と思うようになった • それまでは –
C言語で構造化プログラミング – Oracle データベース中心アプローチ + PL/SQL で手続き型プログラミング • 私にとってオブジェクト指向設計は、 ドメイン駆動設計の実践手段の一つ
21.
ドメイン駆動設計のための オブジェクト指向設計 • 部品化 • 条件分岐と多態 •
制御構造の再利用 • 全体の建てつけ
22.
部品化アプローチ • 集める – 関係するデータとロジックを一つのクラスに –
関連するクラス群をパッケージに • 目的に特化する – 特化:PersonName,Money, ScheduledDate, … – 汎用:String, BigDecimal, Date, … • 業務用語の粒度にあわせた部品 – 「予定日」とか「合計金額」がクラス候補 – クラス=データとロジックの置き場所
23.
区分と分岐 • 区分、種別 – 夏季料金/冬季料金 –
特別会員/一般会員 – 申請中/承認済/実行済 … • 条件分岐で記述? – if/else – switch case
24.
多態 インタフェース宣言と実装クラス • interface 季節料金 –
price () • 実装クラス – class 夏価格 implements 季節料金 – class 冬価格 implements 季節料金 • データとロジックの置き場所 – 夏の期間、夏の料金計算式 → 夏価格クラス – 冬の期間、冬の料金計算式 → 冬価格クラス • 使う側 – どの季節でも、季節料金#price() を呼ぶだけ
25.
多態 オブジェクトの生成と選択 Map<季節名,季節料金> 料金= [ “夏”
: new 夏価格(), “冬” : new 冬価格() ]; price( “夏” ) { 料金.get(“夏”).price(); } enum 季節 { 夏( new 夏価格()) , 冬( new 冬価格() ) ; private 季節料金 料金; 季節( 季節料金 料金) { this.料金 = 料金 } } // 画面アプリケーション // select ボックスを “夏” を選択 季節.valueOf( “夏” ).price() // OR マッピング enum 季節.夏 -> データベースに季節名を保存 データベースの季節名 -> enum.valuleOf(“夏” ) if 夏 return new 夏価格() else return new 冬価格() ※一か所だけ条件分岐が残る
26.
制御構造の再利用 • フレームワーク – IoC
: Inversion of Control (制御の反転) • Control = if/else, switch, for, try-catch-throw, goto … • Inversion:反転の意味 – アプリケーションプログラミング » 制御構造を書く → 制御構造を書かない • たとえば – コレクションフレームワーク と for 文 – バリデーションフレームワーク と if 文 – ORマッピングフレームワーク と for 文/if 文 – MVC フレームワークと switch 文
27.
全体の建てつけ アプリケーションサーバー • アプリケーション起動イベントのリスニング – HTTP
リクエスト、非同期メッセージ、メール受信 – データベース変更、File 追加 • 文脈(Context ) に沿ったアプリケーションの実行 – ターゲットのオブジェクト#メソッドを判定・起動 – 環境依存性の分離(リソースの間接参照 JNDI etc.) – 横断的関心事の実行 ロギング、セキュリティ、… • たとえば – Tomcat ( HTTP リクエストハンドラ) – Active MQ + Mule ESB ( 非同期メッセージハンドラ) – Jame ( メール受信ハンドラ)
28.
補足:パターンについて • パターン – アーキテクチャパターン
: PoEAA, EIP, … – GoF デザインパターン • 確立したパターンは、自分で書く必要はなくなりつつある – GoF のオブジェクト生成パターン • Spring : Bean コンテナ の Bean 生成機能 • Java : enum (singleton) – GoF の Strategy/State パターン • Java : enum – PoEAA のドメインモデルパターンとデータマッパ • OR Mapping ツール – PoEAA のフロントコントローラパターン • Spring MVC Dispatcher Servlet – EIP • Mule ESB
29.
3 ドメイン駆動設計の インプット
30.
主要なインプット ドメイン モデル 最初に手に入れるべき情報 いつも気にすべき情報 機能モデリングの元ネタ データモデリングの元ネタ アーキテクチャ スタイル プロセス スタイル オブジェクト指向 設計スタイル
31.
最初に手に入れるべき情報 全体イメージと方向感 • ビジネス企画書 – トップ向けのプレゼン資料 –
予算申請時の説明資料 • ドメインのガイドブック
32.
いつも気にすべき情報 フィードバック/実験結果 • 同僚の言葉 – ビジネス企画書の言葉を使っている? –
ドメインガイドブックの言葉を使っている? – それは画面イベント(ボタン)駆動では? – それはデータ操作命令では? • 利用者の反応/利害関係者の言葉 – モデルに登場しているか? – モデルで説明できるか?
33.
データモデリングの元ネタ • 画面 – ワイヤーフレーム –
項目定義書 • 帳票 – サンプル – レイアウト、項目定義書 • 既存データベース – DDL – ER 図 • 外部インタフェース – ファイル仕様書 – サンプルファイル
34.
機能モデリングの元ネタ • 機能要求 – 機能要求一覧 –
ユースケース一覧/ユースケース記述 – バックログアイテム、ユーザーストーリー、… – 画面遷移図、画面イベント一覧 • ユーザマニュアル、オンラインヘルプ – 既存システム – 類似システム • 業務体系 – 業務マニュアル – 組織表、職務分掌規程
35.
データと機能 ハイブリッドなアプローチ • データの視点 – 業務で使うデータを洗い出して構造化(データクラス) –
データの識別キーとデータ整合性 – 「一覧」や「合計」など導出データもクラスとして明示 • ロジックの置き場所の有力な「候補」 • 機能の視点 – 利用者のやりたいこと(機能要求) – 業務の手順、判断ロジック、計算式 – ユースケース、ユーザストーリー、バックログ – 画面遷移、画面イベント • 二つの視点をいったりきたりしながら – データに機能を寄せる – 機能にデータを寄せる
36.
ドメイン駆動設計の基本スタイル • アーキテクチャ – ドメインモデル中心 •
フレームワークの設計思想、利用例 – 非同期メッセージング • ビジネスがそう動いている • プロセス – フィードバックサイクル – 繰り返しのリズム – 身軽、機敏 • オブジェクト指向設計 – データ+ロジック – 目的特化 – 継続的な設計改善(リファクタリング)
37.
ケーススタディ プロジェクト初日のインプット • Aプロジェクト – ビジネス企画書の読み合わせ –
ドメインガイドブックの持ち寄り、ななめ読み • Bプロジェクト – 言語、ミドルウェア、フレームワーク、… – ツール、サーバー環境、コミットルール、… • Cプロジェクト – マスタースケジュール、組織体制図、会議体、… – WBS、マイルストーン、成果物、規約、… • Dプロジェクト – スプリント、バックログ、スタンダップミーティング、… – テスト駆動、ペアプログラミング、継続的デリバリ、…
38.
4 ドメインモデルの 実装パターン
39.
実装パターン • 目的特化 • かたまり •
永続化 • アプリケーションインタフェース
40.
目的特化 ドメインモデルの基礎部品 • 日付、期間、数量、金額、単位、名称、備考、… – String,
BigDecimal, Date など汎用部品をラッピングし た目的特化部品 – フィールド変数は、ひとつか二つ – 長さ、文字種、形式など目的特化で限定 – ロジックの置き場所 ( getter で値を返さない ) • Value Object パターン – 完全コンストラクタ • すべてのフィールド値を、生成時に決定 – 不変 • setter を書かない • 値の変更は、別のオブジェクトを生成して返す
41.
目的特化 ファーストクラスコレクション • コレクションだけを保持する特別クラス class ItemList
{ private List<Item> } • 汎用インタフェースを必要なものだけに限定 する – add() , size(), … • コレクションの操作ロジックを集約 – for 文 – 集合操作 – コレクションを他クラスに渡さない • どうしても必要なら 不変にして渡す
42.
目的特化 区分、種別、イベント/状態の宣言 • 静的に列挙できる場合 – enum
宣言 • インタフェース宣言+実装クラス群+Singleton Java コンパイラがやってくれる • 外部のマスター定義を読み込む場合 – Map + singleton • Spring の bean 生成 + autowired • イベント/状態 – クラスを分ける • イベント種類ごと • 状態種類ごと – 遷移ロジックをステートパターンで記述
43.
かたまりのパターン • Bounded Context –
チームの関心スコープを明確にする – ユビキタス言語 – 組織パターン • モジュール – 関心事の範囲を明確にするパッケージを宣言 – public スコープは最小限。基本はパッケージスコープ。 – モジュール間の依存関係を最少にする(方向、依存線の数) • Aggregate – 基礎部品 ( Value Oject ) の集合体 – 集合体の識別 • Aggregate の root オブジェクトとしての Entity パターン – 必要なら用途別に Aggregate を用意する • 顧客サマリー(一覧用), • 顧客連絡先 • 顧客履歴
44.
かたまりのパターン Aggregateの利用 • Repository – 業務の関心事「記録」を表現 –
Aggregate 単位の保存/取り出し – インタフェース宣言して実装と分離 • データアクセスへの依存性を逆転させる • Transfer – 業務の関心事「通知」を表現 – 必要なら通知専用の Aggregateを追加 • Factory – 業務の関心事としての Builder パターン • 「準備」や「用意」が複雑な場合
45.
Aggregateと永続化 • データモデルとオブジェクトモデル – データモデル
( データのみ ) • 正規化が原則 • 導出可能データは保存しない • すべての関係は、キーを元に 1 対多として構造化 • 参照方向は「多→1」に固定 • 構造的にデータ整合性を維持する – オブジェクトモデル(データ+ロジック) • 導出データもオブジェクトで表現する – ロジックの置き場所として重要 • 関連の表現の自由度が高い – ネットワーク構造、参照方向、多重度の制約 – データ整合性はロジックで維持する必要がある
46.
永続化 • SQL マッピングのすすめ –
正規化したデータモデルを、SELECT 文でオブ ジェクト用に冗長化してマッピングする • 危険な臭い – OR マッピングの隠ぺいや SQL自動生成 • オブジェクトが、データの入れ物の設計だけにな りがち • ドメインモデル(オブジェクトモデル)の設計改 善の制約になりがち
47.
サービス層 データベース OR マッピング 2 5 アプリケーション サービス (API宣言) 3 ドメイン モデル 1 機能テスト 4
48.
サービス層 アプリケーションインタフェース • アプリケーションインタフェース – アプリケーションとドメインモデルの接点 •
業務機能の宣言(ユースケースの実現) – 登録()、記録()、作成()、… – 参照()、検索()、絞り込み()、… – キャンセル()、取り消し()、訂正()、… • 業務手順の記述 – 検証() , 記録(), 通知() 3行程度の手続きを記述 – 判断、計算、加工はドメインモデルに委譲する
49.
おわりに
50.
アプリケーションの中核部品 ドメインモデル 画面 アプリケーション 連携 アプリケーション 帳票 アプリケーション データベース ドメイン モデル ここに 業務ロジックを 集める
51.
なぜドメイン駆動設計か? • コード量が減る – 重複しがちなコードを、データ構造を軸に整 理・統合する –
業務ロジックが、プレゼンテーション層、 データアクセス層から消えていく • 手戻りが減る – 業務の仕組み/こだわりポイント/やるべき こと • メンバー個人に内面化 • チーム共有の暗黙知の発達
52.
お誘い オブジェクト設計エクササイズ チームモデリングで学ぶドメイン駆動設計 2013/10/05 (土) 13:30
- 16:30 開催場所 : mixi 渋谷区東1-2-20 住友不動産渋谷ファーストタワー7F 参加費:五千円 内容: チームにわかれて、ドメインモデリングを実際にやってみる • イテレーション 3回を予定 • 業務知識が豊富なドメインモデルに育てる • モデルとコードを結びつける • モデルの洗練 • モデルの検証
53.
ありがとうございました
Download