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