Mais conteúdo relacionado
Semelhante a ドメイン駆動設計 の 実践 Part3 DDD (20)
ドメイン駆動設計 の 実践 Part3 DDD
- 4. 捻じれて歪む構図
プレゼン資料
エクセル
画面イメージ
動くソフトウェア
ちんぷん
かんぷん
わからないまま
エクセル なんかがんばる
参考システム スクリーンショット ソースコード
仕様 DDL
Java
XML
…
動いているが正しくないソフトウェアの完成
- 5. 処方箋:ドメイン駆動設計
業務の知識だけを記述したクラス群を、まず設計・実装する
それをソフトウェアの基盤に配置する
ドメインモデルパターン
PoEAA : Pattern Of Enterprise Application Architecture
業務の用語が、そのまま、クラス名とメソッド名になる
業務の単位が、そのままパッケージ名になる
業務モデリングとドメインモデルの設計を常に一致させる
分析開始=ドメインモデル設計開始
分析モデル=ドメインモデル (粒度、構造、命名)
関係者は、業務の言葉でコミュニケーションする
分析に開発者も最初から参加(ドメインモデルの設計開始)
ドメインモデルのレビューに業務エキスパートが参加
コミュニケーションの語彙は「業務の用語」
記法は、UML(形式的かつ視覚的な言語)
- 9. ドメインモデル中心に作る
<<use>>
web.jar
ビューと
コントロール
<<use>>
業務の知識
ソフトウエアの核心
<<use>> 業務機能
application-service.jar (ファサード)
domain-model.jar
<<use>>
<<use>>
repository.jar データベースアクセス
ソフトウェア全体が、業務のモデルを反映した構造になる。
- 10. イベント・ソーシング
「記録」と「通知」が業務の二大関心事
業務イベントが発生したら、データベースに記録
業務イベントが発生したら、しかるべきところに通知
技術方式も、これを反映する
データベース
業務イベントをデータベースに Insert オンリーで記録
「状態」は、上記のイベント記録時に更新 (トリガー)
「入庫・出庫」記録が「正」。「在庫数」は「派生データ」
非同期メッセージング
業務イベントが発生したら、非同期でメッセージ送信
データベースのトリガー+ Mule ESB のデータベースポーリング
RESTスタイル API
バッチ処理の激減
「予定/約束」と「リマインド/アラート」
一定期日までに、起こすべき業務イベント(予定/約束)を記録
直前にリマインドイベントを生成して、通知
期限切れは、アラートイベントを生成して、通知
- 11. コードではなく、モデルで議論
ドメインモデル設計の関心事(業務の言葉が登場する場所)
パッケージ名
パッケージ間の依存関係
クラス名
クラス間の関連
メソッド名
オブジェクトの特定方法 (業務での識別方法/体系)
クラス図(パッケージ図)がわかりやすい
コードはノイズが多い
依存関係や関連は、コードから読めない
コードでは全体を俯瞰できない
ドメインモデルのクラス図とコードは、常に一致させる
モデルを変更したらコードを変更する
コードを変更したらモデルを変更する
- 12. ドメインモデル設計の情報源
ドメインエキスパートとの対話
とってもたいへん
こっちがあまりにも、業務を知らなすぎる
エキスパートの頭の中を見ることはできない
基本用語は、仕込んでおく (ドメインクラス候補)
企業のホームページ
問題領域の解説本(初心者向け)
問題領域の解説本(英語→命名の元ネタ)
既存システムの画面、実データ
問題領域の基本構造
解説本の章立て → パッケージ構造
ドメインモデルの設計パターン Google 検索
- 13. ドメインモデリング中心に進める
要件分析・要件定義 RDRA(リレーションシップ駆動要件定義)
ユースケースごとに開発
システム価値 システム境界 システム
システム外部環境 (ICONIX)
ユースケース 画面・帳表
業務フロー図 ロバストネス図
コンテキスト図 要求図 予備設計
イベント プロトコル
利用シーン記述
詳細設計
ドメインモデル 属性追加 シーケンス図
基盤クラス追加
初期概念モデル Java
操作追加
概念モデルの洗練 ソースコー
パッケージ構造 ド
中核クラス 関連クラス
依存クラス データモデル DDL/SQL
ソースコー
クラスとテーブルの設計・実装 ド
- 15. 「業務の関心事」の分離
業務知識がUIのコードに埋 注文 注文
もれている 入力画面
オブジェクト 顧客名
画面定義(View)から業務の 注文金額
関心事を抽出する 合計()
コントローラから、業務ロジッ
クをメソッドに抽出 submit() { }
注文明細
金額計算()
業務ロジックを、ドメインオブ 商品
ジェクトに移動 数量
単価
金額
業務の関心事だけ取り出して、別クラスにする 金額()
- 17. 条件記述から業務ロジックを抽出
宿泊予約
宿泊予約
料金()
料金() is夏季()
夏料金()
冬料金()
If ( date.before( SUMMER_START ) If ( isSummer( date ) )
|| date.after( SUMMER_END ) ) {
{ charge = summerCharge() ;
charge = quantity * winterRate + winterFee ; }
} else
else {
{ charge = winterCharge()
charge = quantity * summerRate ; }
}
クラス内に業務の知識の記述が増えた
- 18. コレクションのカプセル化
技術的な関心 → 業務の関心
顧客 顧客
List<注文> 購買履歴
setList() 履歴に追加(注文)
getList() 最後の注文()
平均購買額()
List<Order> orderHistory =
List<Order> orderHistory ; new ArrayList<Order>();
void setHistory( List<Order>) void record( Order )
Order getLastOrder()
List<Order> getHistory() Amount totalPurchase()
業務でやりたいことがクラスに登場
- 19. 単なる値を
ドメインのオブジェクトに置き換える
注文 注文 顧客
String 顧客 氏名
連絡先
class Order
class Order {
{ Customer customer ;
String customer; }
}
class Customer
{
String name ;
}
業務の重要な関心事(顧客)を記述する入れ物ができた
- 22. <<façade>>
ゴールド会員登録サービス
ゴールド会員登録 Service
<<entity>> 購入履歴
すべて情報 会員
会員リポジトリ
会員番号
すべての操作 氏名 支払記録
http 依存の
関心事の分離
<<service>>
view定義と 購買額が多く ゴールド会員認定ポリシー 変更が簡単で安全になる
control 支払事故がない ソフトウェアを育てやすい
を抽出 <<value>>
<<entity>>
与信限度額 ゴールド会員
ゴールド会員
DB ファクトリ
アクセス 会員番号 <<value>>
を抽出 氏名 有効期限
承認が必要 <<service>>
ドメイン層の ゴールド会員認定手続き
いろんな トランザクション <<transfer>>
ロジック 承認依頼
スクリプト? ゴールド会員リポジトリ