45
有限会社 システム設計 増田 亨 ブログ: システム設計日記 (http://masuda220.jugem.jp/ ) Twitter http://twitter.com/masuda220

ドメイン駆動設計 ( DDD ) をやってみよう

  • Upload
    -

  • View
    15.780

  • Download
    1

Embed Size (px)

DESCRIPTION

ドメイン駆動設計  Domain-Driven Design ( DDD )  準備 / スタートアップ / ブラッシュアップ / チャレンジ / 参考書籍 /

Citation preview

Page 1: ドメイン駆動設計 ( DDD ) をやってみよう

有限会社 システム設計 増田 亨 ブログ: システム設計日記 (http://masuda220.jugem.jp/) Twitter : http://twitter.com/masuda220

Page 2: ドメイン駆動設計 ( DDD ) をやってみよう

DDD: Domain-Driven Design ドメイン駆動設計

役に立つソフトウェアを

楽しく作る

ドメインモデル中心で

Page 3: ドメイン駆動設計 ( DDD ) をやってみよう

ドメインモデル?

ドメインモデル 利用者の関心ごとの模型

コード

com.systemsekkei.model .* 利用者の関心ごとの実装

Page 4: ドメイン駆動設計 ( DDD ) をやってみよう

DDD こだわりポイント

ドメインモデル 利用者の関心ごとの模型 この設計・実装を開発の中心にする

設計駆動開発 原則:設計してからコード もうひとつの DDD : Design-Driven Development

Evolve 少しずつ、継続的に成長

iterate(反復) increment(増分) continuous(絶え間なく)

モデル駆動設計 MDD: Model-Driven Design 言葉と絵で、関心ごとの模型を作って、設計、実装

Page 5: ドメイン駆動設計 ( DDD ) をやってみよう

いろいろあるよね xDD テスト駆動開発(TDD)

振舞い駆動開発(BDD) ユースケース駆動開発(UCDD)

画面駆動開発(ScrDD?)

チケット駆動開発(TiDD)

エクセル駆動開発(ExDD)?

リスク駆動・アーキテクチャ中心(RD/AC)

Page 6: ドメイン駆動設計 ( DDD ) をやってみよう

華麗で楽しい? シングル xDD

Page 7: ドメイン駆動設計 ( DDD ) をやってみよう

悪路走破には、四輪駆動

マルチ xDD

Page 8: ドメイン駆動設計 ( DDD ) をやってみよう

より速く、より効率的に

ポルシェ911ターボを上回る加速性能 ポルシェの10倍の燃費効率

8輪駆動

駆動力の分散配置 (8つのインホイールモータ&変速ギヤ)

8輪の協調動作 (センサーとシグナル同期) 電気自動車エリーカ

Page 9: ドメイン駆動設計 ( DDD ) をやってみよう

リスク 駆動

エクセル

駆動

テスト 駆動

チケット

駆動

振舞 駆動

ユースケース

駆動

画面 駆動

DDD的8輪駆動

ドメイン 駆動

ユーザ受入テスト重視

動きと構造の補完関係 ドメインモデル=構造設計

最大リスク: 利用者の関心ごとの理解不足

ドメインモデルの 作成、改良チケット先行

アーキテクチャの中核を

ドメイン層に

重要な情報源 伝達手段

Page 10: ドメイン駆動設計 ( DDD ) をやってみよう

ドメイン駆動設計を実践すると

利用者の要求の キャッチ力が高まり

利用者の関心ごとの 構造が見えてきて

要件の 追加や変更が

簡単で安全になる

Page 11: ドメイン駆動設計 ( DDD ) をやってみよう

DDDはソフトウェア設計 設計原則:関心の分離

SRP : 単一責任原則 カプセル化、情報隠蔽 モジュール化(凝集)

...

設計原則:協調 疎結合:必要最小限の結合関係 モジュール化(公開インタフェースの最小化)

...

設計原則を

ドメインモデルの 設計・実装で実践する

Page 12: ドメイン駆動設計 ( DDD ) をやってみよう

基本パターン: Whole-Part

全体

部品A 部品N ...

それぞれの部品の役割は? ・関心ごとの分離 ・単一責任原則

どんな部品を、どんな構造でまとめるか? 部品群を、どうコントロールするか? もっと部品に委譲できないか?

利用者に有用で、かつ、最もシンプルなインタフェースは?

(関心の分離)+(協調)の基本パターン 繰り返し、適用シーンがでてくる、基本中の基本パターン

Page 13: ドメイン駆動設計 ( DDD ) をやってみよう

準備とトライアル

Page 14: ドメイン駆動設計 ( DDD ) をやってみよう

DDD 実践シナリオ 利用者の関心ごとの置き場所を作る

利用者の関心ごとを見つける

利用者の関心ごとをコードにしてみる

利用者の関心ごとの妥当性を検証する

利用者の関心ごとの改善点を発見する

Page 15: ドメイン駆動設計 ( DDD ) をやってみよう

関心の分離(1)

画面 UIコントローラ

メッセージング

メール送信

DBアクセス

Page 16: ドメイン駆動設計 ( DDD ) をやってみよう

置き場所の追加

画面 UIコントローラ

メッセージング

メール送信

DBアクセス

利用者の関心ごと を記述する場所

Page 17: ドメイン駆動設計 ( DDD ) をやってみよう

依存関係

画面 UIコントローラ

メッセージング

メール送信

DBアクセス

利用者の関心ごとを 記述するクラス群

利用する 利用する

利用する

利用する

誰から使われているか知らない

利用する

Page 18: ドメイン駆動設計 ( DDD ) をやってみよう

利用者の関心ごとクラス

顧客 << domain object >>

連絡方法 通知先() : メールアドレス

利用する

画面 UIコントローラ DBアクセス

メール送信

メッセージング

顧客登録サービス << application controller >>

呼び出す 顧客リポジトリ << interface >>

登録する() : void 存在を確認(顧客) : Boolean 利用する

実装する

顧客トランスファー << interface >>

Thank Youメール送る(顧客) : void 関係部門に通知する(顧客) :void

利用する

実装する

実装する

Page 19: ドメイン駆動設計 ( DDD ) をやってみよう

私たちが使っている実装技術

顧客 << domain object >>

連絡方法 通知先() : メールアドレス

画面 UIコントローラ

メッセージング

メール送信

DBアクセス

Spring MVC

Spring Mail

Spring JMS

Spring Bind Bean Validation

Velocity テンプレート

Spring ORM MyBatis SQLマップ

Apache James

ActiveMQ Mule ESB

Spring Web Flow

Page 20: ドメイン駆動設計 ( DDD ) をやってみよう

DDD 最初の一歩

パッケージ com.clientname.applicationname.model をつくる

業務データの入れ物を、最低ひとつ、追加する --- Customer.java

業務ロジックメソッドを、最低一つ、追加する --- MailAddress contactTo()

顧客の言葉/業務要件を手掛かりに ・サブパッケージ追加 ・クラス追加 ・フィールド追加 ・メソッド追加

繰り返す

ごちゃごちゃしてくるので 整理整頓 ・名前の変更 ・クラスの移動 ・フィールドの移動 ・メソッドの移動

とりあえず置き場所を作って、そこにドメインクラスを作って、 UIクラスやコントローラクラスから利用してみる

Page 21: ドメイン駆動設計 ( DDD ) をやってみよう

スタートアップ まずは、やってみる つまづく 本を漁る 試してみる 工夫してみる

対象業務のハンドブックや入門書

英語本は、ドメインモデルの ・パッケージ名 ・クラス名 ・メソッド名 の宝庫

Page 22: ドメイン駆動設計 ( DDD ) をやってみよう

リファクタリング (設計の改善)

Page 23: ドメイン駆動設計 ( DDD ) をやってみよう

「業務の関心ごと」の分離 業務知識が

UIのコードに埋もれている 画面オブジェクトから

業務の関心ごと情報を抽出 コントローラから、

業務ロジックを抽出 業務ロジックを、

ドメインオブジェクトに移動

注文入力 画面オブジェクト

注文

顧客名 注文金額

商品 数量 単価 金額

注文明細 submit() { }

金額計算()

合計()

金額() 業務の関心ごとだけ取り出して、別クラスにする

データ

Page 24: ドメイン駆動設計 ( DDD ) をやってみよう

手続型の設計(手続+データ)を ドメインオブジェクトにリフォーム

注文

顧客名 注文金額

商品 数量 単価 金額

注文明細

注文

顧客名 注文金額

商品 数量 単価 金額

注文明細

金額() 税額()

合計() 税額()

Order Calculator

合計() 税額算出()

業務のロジックは、情報の近く に移動する 業務データと業務ルールをまとめる

Page 25: ドメイン駆動設計 ( DDD ) をやってみよう

条件記述から業務ロジックを抽出 宿泊予約

料金()

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() }

クラス設計に業務の記述を増やす

Page 26: ドメイン駆動設計 ( DDD ) をやってみよう

コレクションのカプセル化 技術的な関心 → 業務の関心

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<注文>

顧客

履歴に追加(注文) 最後の注文() 平均購買額()

購買履歴

業務でやりたいことをメソッドで表現

Page 27: ドメイン駆動設計 ( DDD ) をやってみよう

単なる値を ドメインオブジェクトに昇格する

class Order { String customer; }

class Order { Customer customer ; } class Customer { String name ; }

注文

String 顧客

顧客

氏名 連絡先

注文

業務の重要な関心ごと(顧客)を記述する入れ物を作る

Page 28: ドメイン駆動設計 ( DDD ) をやってみよう

設計のヒント、パターンの利用

Page 29: ドメイン駆動設計 ( DDD ) をやってみよう

ドメインモデル設計パターン 業務ドメインによく出てくる設計パターン

用語や概念 何が関心ごとか? どう設計するか?

パターン集の目次 さまざまな関心ごとを俯瞰する全体マップ

パターン=設計のヒント 関心の分離のしかた 協調のさせ方

Page 30: ドメイン駆動設計 ( DDD ) をやってみよう

参考書籍 masuda220 リストマニア「ドメインモデル設計パターン」@アマゾン

ドメイン駆動設計 by Evans まえがき、第1部 ビジネスパターンによるモデル駆動設計 by Hruby

2章 構造パターン、5章 振舞パターン アナリシスパターン by Fowler A.1.5 基本型 PoEAA by Fowler はじめに、2章 ドメインロジックの選択 リファクタリング by Fowler 3章 変更の発散、変更の分散 ストリームラインオブジェクトモデリング by ニコラ

3章 協調パターン UML によるビジネスモデリング by エリクソン

5章ビジネスルール The Data Model Resource Book 1,2,3 Data Model Patterns by Hay

Page 31: ドメイン駆動設計 ( DDD ) をやってみよう

Value Object 基本語彙の設計・実装パターン String, BigDecimal, Date/long のラッパー 型宣言 -> 表現力の向上

氏名、社名、… 金額、数量、日数、… 登録日、締切日、…

不変 -> 振舞の安定 パラメータ付コンストラクタで生成 set メソッド禁止 演算結果は、新たにオブジェクトを生成して返す

String と同じ

Page 32: ドメイン駆動設計 ( DDD ) をやってみよう

6つの役割で考える オブジェクトデザイン by ワーフスブラック

全体

部品A 部品N

部品群の構造化 <<structurer>>

情報保持 <<information holder>>

サービス(演算)提供 <<service provider>>

制御役 <<controller>>

調整役 <<coordinator>>

If/for を 持つ/持たない の違い

外部への見せ方 <<interface>>

Page 33: ドメイン駆動設計 ( DDD ) をやってみよう

識別にフォーカスしたクラス 識別番号(参照番号)

発番方法 一意性確保/検証

認証 番号と実体の照合方法、記録

識別名 氏名、品名、… 一意でなくても良い。人間にとっての判断材料。

DDD Entity パターン

Page 34: ドメイン駆動設計 ( DDD ) をやってみよう

手順やルールをクラスにまとめる Procedure クラス

業務の手順 コンピューティング手順 状態を持たない

Policy クラス オーバーブッキングポリシー キャンセルポリシー 状態を持たない

Rule クラス Policy クラスの部品

Page 35: ドメイン駆動設計 ( DDD ) をやってみよう

集約、モジュール、リポジトリ いつもいっしょに扱う単位

例:注文ヘッダーと明細 例:顧客Entityと連絡先

パッケージ宣言でモジュール化 全体クラス Publicで公開 部品クラス デフォルトで隠蔽

リポジトリで一体操作 格納する塊(ヘッダと明細) 取り出す塊

全体

部品A 部品N

Page 36: ドメイン駆動設計 ( DDD ) をやってみよう

その他の参考パターン(1) グルーピング、関連づけ、構造化

「一覧」 <---- List クラスのラッパー 分類(クラス分け、カテゴリー) グループ /メンバー 、コンテナ/コンテンツ、アセンブリ/パーツ セット(商品)、パッケージ(販売), オプション・アダプタ・アクセサリ…

予定、約束 スケジュール 契約

通知、連絡、申し送り 責任・権限

部門、役割、ポスト 承認ルート 兼任

Page 37: ドメイン駆動設計 ( DDD ) をやってみよう

その他の参考パターン(2) 照合

多対多の解決 例:売上計上、締と請求、入金消込

日付 予定日、残日数、期限切れ 期間、間隔 日付演算

金額・数量 単位換算 数値演算と精度

場所 識別方法

経度緯度、郵便番号、都道府県・市区町村、番地、最寄駅、沿線、… 包含関係

Page 38: ドメイン駆動設計 ( DDD ) をやってみよう

その他の参考パターン(3) ドメインモデル内の階層化 (関心ごとの分離)

意思決定層 ポリシー、プロシージャ層 オペレーション層

イベント:注文、入出庫、… ステート:残高、〇〇中,△△待ち、 …

リソース(商品、場所、… )層

Page 39: ドメイン駆動設計 ( DDD ) をやってみよう

チャレンジテーマ

1. 隣接ドメインと領域の重なり 2. 状態遷移とコミュニケーション 3. イベントソーシング 4. 基本構造の複雑化 5. 時系列変化

Page 40: ドメイン駆動設計 ( DDD ) をやってみよう

隣接ドメインと領域の重なり 同じもの?

発注/受注/注文 見込み客、顧客、契約者、出荷先、請求先、…

作り方は? 中核部分を共有して密結合? 支援部分を部品として共有? 別々に作って、疎結合? 別々に発展させる vs. 寄せていく

Page 41: ドメイン駆動設計 ( DDD ) をやってみよう

状態遷移 業務ルールの宝庫

修正可否、取消手順、アラート、締切、督促、… モデリングテクニック

状態機械 (イベント・ステートモデル) 状態遷移表 論理的に記述・検証でき、実装も安定する。

利用者(業務専門家)の用語(メンタルモデル)とのギャップ 「状態」「○○中」「△△待ち」, …

言葉の意味がそもそも違う? (状態機械ではない?) コミュニケーションのハードル モデルの間違いの発見の遅れ テストの自動化

Page 42: ドメイン駆動設計 ( DDD ) をやってみよう

イベントソーシング ビジネスプロセス=イベント駆動 イベントソーシング

元データは、イベントの発生記録(伝票) ステート(残高や状態、帳簿)は、派生(再構築可能)

非同期メッセージング ドメイン駆動アーキテクチャの実装技術 業務モデルと親和性が高い(はず) DBアプリケーション(OLTP)が先行したが、今後の有望分野

課題 モデリング (非同期、並行処理、エラー処理、リトライ、同期ポイント) 設計 (特に、イベントハンドラの変更容易性) 実装 テスト (特にテスト自動化)

Page 43: ドメイン駆動設計 ( DDD ) をやってみよう

扱う情報の構造の複雑化 かつては、単純で、固定ロジックで対応できた

リスト構造 (線形、連番、順序処理) 単純なツリー構造 (大中小3分類、…)

より複雑な構造への要求・期待 マトリクス、キューブ、 ファセット、… ( 多軸の分類整理 ) ネットワーク構造 (関係付けが、縦横無尽)

よりアナログ(=人間感覚)に近づける あいまい/関係づけ/重みづけの検索や判断 Fuzzy 「らしさ」「感覚値」のデータ化と処理ロジック

Page 44: ドメイン駆動設計 ( DDD ) をやってみよう

時系列の変化 変更履歴、追跡、復元、 予定、推定、…

異動、組織変更、合併・分社化、… 価格改定、価格変動 評価額、為替レート、… 予定・実績・差異 先物、リスク管理、タイミング管理、…

Page 45: ドメイン駆動設計 ( DDD ) をやってみよう

ありがとうございました。