ドメインモデルの育て方

9,014 views

Published on

BPStudy #82 2014/6/27 ギルドワークス「正しいものを正しくつくる」、市谷さんとの合体発表。 ドメイン駆動設計。

Published in: Software
2 Comments
29 Likes
Statistics
Notes
No Downloads
Views
Total views
9,014
On SlideShare
0
From Embeds
0
Number of Embeds
637
Actions
Shares
0
Downloads
71
Comments
2
Likes
29
Embeds 0
No embeds

No notes for slide

ドメインモデルの育て方

  1. 1. ドメインモデルの育て方 ギルドワークス 増田 2014年6月27日 ソフトウェアを正しく作るための BP Study #82
  2. 2. 現実世界/モデルとコード 現実世界 モデル (模型) ソースコード 単純化 コードで 表現 動くソフトウェア
  3. 3. 現実世界/モデルとコード 現実世界 モデル (模型) ソースコード 単純化 コードで 表現 動くソフトウェア 一回では うまくいかない 一回では うまくいかない
  4. 4. モデリングと設計のパラダイム • 画面・帳票モデル – 画面一覧、画面遷移図、項目定義書、… スマートUI
  5. 5. モデリングと設計のパラダイム • 画面・帳票モデル – 画面一覧、画面遷移図、項目定義書、… • 機能モデル – 機能一覧、入出力項目定義、処理詳細、… スマートUI トランザクション スクリプト
  6. 6. モデリングと設計のパラダイム • 画面・帳票モデル – 画面一覧、画面遷移図、項目定義書、… • 機能モデル – 機能一覧、入出力項目定義、処理詳細、… • データモデル – ER 図、テーブル一覧、テーブル定義書、… スマートUI トランザクション スクリプト Active Record
  7. 7. モデリングと設計のパラダイム • 画面・帳票モデル – 画面一覧、画面遷移図、項目定義書、… • 機能モデル – 機能一覧、入出力項目定義、処理詳細、… • データモデル – ER 図、テーブル一覧、テーブル定義書、… • オブジェクトモデル – パッケージ図、クラス図、コラボレーション図、… スマートUI トランザクション スクリプト Active Record ドメイン モデル
  8. 8. 三層+ドメインモデル プレゼンテーション層 アプリケーション層 データソース層
  9. 9. 三層+ドメインモデル プレゼンテーション層 アプリケーション層 データソース層 OrderForm.vm OrderConfirm.vm OrderRegistered.vm @Controller class OrderEntryController … // bind & validate @Service class OrderRegisterService … void register( Order order ) @Repository class OrderDatasource … void save( Order order )
  10. 10. 三層+ドメインモデル プレゼンテーション層 アプリケーション層 データソース層 OrderForm.vm OrderConfirm.vm OrderRegistered.vm @Controller class OrderEntryController … // bind & validate @Service class OrderRegisterService … void register( Order order ) @Repository class OrderDatasource … void save( Order order ) ドメインモデル class Order class Items class ShipTo class BillingTo class ContactInfo … interface OrderRepository <<use>> import model.Order ロジックの抽出と移動 矢印の意味
  11. 11. プロジェクトの進行モデル • プロジェクト初日 – 顔合わせとご挨拶、プロジェクトの概要説明
  12. 12. プロジェクトの進行モデル • プロジェクト初日 – 顔合わせとご挨拶、プロジェクトの概要説明 • 仕様が具体的になり始める – 打合せ、ドキュメント、…
  13. 13. プロジェクトの進行モデル • プロジェクト初日 – 顔合わせとご挨拶、プロジェクトの概要説明 • 仕様が具体的になり始める – 打合せ、ドキュメント、… • コード量が急速に増え始める – 開発環境が整って、人が集まって、リズムがでてき た
  14. 14. プロジェクトの進行モデル • プロジェクト初日 – 顔合わせとご挨拶、プロジェクトの概要説明 • 仕様が具体的になり始める – 打合せ、ドキュメント、… • コード量が急速に増え始める – 開発環境が整って、人が集まって、リズムがでてくる • 開発終盤 – 仕様の変更/追加/再定義、バグとの戦い、性能問題
  15. 15. プロジェクトの進行モデル • プロジェクト初日 – 顔合わせとご挨拶、プロジェクトの概要説明 • 仕様が具体的になり始める – 打合せ、ドキュメント、… • コード量が急速に増え始める – 開発環境が整って、人が集まって、リズムがでてきた • 開発終盤 – 仕様の変更/追加/再定義、バグとの戦い、性能問題 • リリース後 – 障害(バグの発覚)、積み残し開発、追加開発、…
  16. 16. 1.プロジェクトの初日の設計 • パッケージ図 顧客 商品 注文 出荷 売上・請 求・回収 値引き 返品 <<use>> ( = import 文) 業務の基本構造 =プログラムの基本構造 参照関係の「複雑」さや「あいまい」さが、設計課題を暗示している ? ? ?
  17. 17. 2.仕様が具体的になりはじめたら • ドメインモデルの基礎部品を増やしていく – 値オブジェクト – 振る舞いを持った区分 – ファーストクラスコレクション • 要求に出てくる「言葉」をマッピング – パッケージ名 – クラス名 – メソッド名 • コード量とクラスの数は比例する – クラスの数が変わらずコードが膨らみはじめたら警戒 警報
  18. 18. ドメインモデルの初期の育て方 日付 期間 予定日 有効期限 場所 地域区分 商品種類 顧客区分 単価 数量 税率 型式 翌月 拠点 キャンペーン Event (出来事) アプリケーションサービス Reference (参照/追跡) Repository (記録) Transfer (通知) Policy (判断) (制約) 部門 役割 担当者一覧 ドメインモデルの基礎部品 端数 超重要 ここを 重点的に 育てる ユースケースの実装 業務の主な 関心事 受注一覧
  19. 19. 値オブジェクト String StringBuilder List<String> BigDecimal Integer Caleldar Date/Long 起算日(InitialDate) 期限(DueDate) 有効期間(ValidTerm) 金額(Money) 数量(Quantity) 単位(Unit) 商品名称(ProductName) 備考(Remarks) 摘要(Abstract) +業務ロジック +業務ロジック +業務ロジック ドメイン固有の「型」を準備する 実装の詳細を隠ぺいする
  20. 20. 振る舞いを持った区分 Enum MemberType //会員区分 { normal, silver, gold; Rate chargeRate() String description() Boolean isLimitOver() } 「区分」や「種別」はビジネスルールの存在を示唆 ビジネスルールを記述する場所を準備
  21. 21. ファーストクラスコレクション (Customers) (OrderLines) (UsageHistory) (ToDoList) (UnReads) (Candidates) 顧客一覧 注文明細 利用履歴 To-do リスト 未読一覧 選択候補 ビューの一覧画面にほぼ対応する 業務の関心事が集中することが多い ・識別情報/区分/状態をすべて一覧したい ・関心事によって、検索条件と並び順を変えたい コレクションのカプセル化 private なコレクション宣言 + public なメソッド群
  22. 22. 3.コード量が急速に増え始める • 失敗パターン – 画面単位や機能単位に分担して並行開発 – ビュー、コントローラ、サービスクラスがファットになる – コードの重複 → 変更コストの増大 • 成功パターン – ドメインモデルに業務ロジックを集め続ける – 共有のドメインモデルをみんなでがんがんいじる – 痛い目に合う – そこで逃げない – みんなで会話しながら同じモデルを追いかける
  23. 23. 4.開発の終盤 • 時間との闘い – 仕様の変更・追加・再定義 – バグとの戦い – 性能問題 • 現実 – モデル一貫性よりも、とにかく修正する – ただし、リファクタリングしたほうが結局は早くて確実なことが多い (スキルレベルによるけど) • Interface と実装の分離 (多態の導入) • 間接化(第3のクラスを導入して、クラスAとBの依存関係を無くす) • できれば – リファクタリングする – 最低限、マークしておいて、リファクタリング勉強会のネタにする – それが次のモデル・設計・開発の糧になる
  24. 24. 5.リリース後 • いろいろ起きる – 障害(バグの発覚) – 積み残し分の開発 – 追加開発 • ドメインモデルの真価がわかる時 – 業務を単純化したモデルが正しいか – モデルをうまくコードで表現できているか • 良いドメインモデルに成長していれば 変更は「楽」で「安全」になる – 修正箇所の特定 – 修正範囲の局所化 – 副作用の局所化 • リリース後のソフトウェアの成長に立ち会い続けること が、ドメイン駆動設計を会得する王道
  25. 25. 現実世界/モデルとコード 現実世界 モデル (模型) ソースコード 単純化 コードで 表現 動くソフトウェア 一回では うまくいかない 一回では うまくいかない
  26. 26. 三層+ドメインモデル プレゼンテーション層 アプリケーション層 データソース層 OrderForm.vm OrderConfirm.vm OrderRegistered.vm @Controller class OrderEntryController … // bind & validate @Service class OrderRegisterService … void register( Order order ) @Repository class OrderDatasource … void register( Order order ) ドメインモデル class Order class Items class ShipTo class BillingTo class ContactInfo … interface OrderRepository <<use>> import model.Order ロジックの抽出と移動 矢印の意味

×