23
業務の言葉で開発を駆動していく 有限会社 システム設計 増田 ブログ: システム設計日記 (http://masuda220.jugem.jp/ ) Twitter http://twitter.com/masuda220

ドメイン駆動設計 の 実践 Part3 DDD

  • Upload
    -

  • View
    5.882

  • Download
    6

Embed Size (px)

DESCRIPTION

2011/6/20 redajp

Citation preview

Page 1: ドメイン駆動設計 の 実践 Part3 DDD

業務の言葉で開発を駆動していく

有限会社 システム設計 増田 亨

ブログ: システム設計日記 (http://masuda220.jugem.jp/)

Twitter : http://twitter.com/masuda220

Page 2: ドメイン駆動設計 の 実践 Part3 DDD

ドメイン駆動設計とは何か?「エリック・エヴァンスのドメイン駆動設計」

Eric Evans “Domain-Driven Design” (DDD)

できるソフトウェア開発者たちは、30年以上も前から、問題領域の理解が、ソフトウェア開発の「肝」 であることを知っていた。

そのノウハウや考え方を集めて、「ドメイン駆動設計(DDD)」という名前を付けてみた。

Page 3: ドメイン駆動設計 の 実践 Part3 DDD

ドメイン駆動設計でない開発業務モデルとソフトウエアの実装が捻じれて歪んでいる

ソフトウェアの実装が

業務の知識をまちがって記述

業務の関心事より、技術の関心事を記述

その結果、業務のごく自然な変更要求が

既存のコードへの不自然・不合理・無理難題になる

変更すると、おもわぬところに副作用が発生する

そのソフトウェアは動いているが、正しくない。

Page 4: ドメイン駆動設計 の 実践 Part3 DDD

捻じれて歪む構図プレゼン資料エクセル画面イメージ

参考システム仕様

エクセルスクリーンショットDDLJavaXML…

ちんぷんかんぷん

わからないままなんかがんばる

動くソフトウェア

ソースコード

動いているが正しくないソフトウェアの完成

Page 5: ドメイン駆動設計 の 実践 Part3 DDD

処方箋:ドメイン駆動設計 業務の知識だけを記述したクラス群を、まず設計・実装するそれをソフトウェアの基盤に配置する ドメインモデルパターン

PoEAA : Pattern Of Enterprise Application Architecture

業務の用語が、そのまま、クラス名とメソッド名になる

業務の単位が、そのままパッケージ名になる

業務モデリングとドメインモデルの設計を常に一致させる 分析開始=ドメインモデル設計開始

分析モデル=ドメインモデル (粒度、構造、命名)

関係者は、業務の言葉でコミュニケーションする 分析に開発者も最初から参加(ドメインモデルの設計開始)

ドメインモデルのレビューに業務エキスパートが参加

コミュニケーションの語彙は「業務の用語」

記法は、UML(形式的かつ視覚的な言語)

Page 6: ドメイン駆動設計 の 実践 Part3 DDD

ドメイン駆動設計の効果うまく設計したドメインモデルを中核にしたシステムは、ソフトウェアの変更を、劇的に、簡単に、安全にする業務の知識を正しく反映した記述、構造

変更箇所の特定が楽で、副作用の心配が少ない

変更(=ソフトウェアを育て続ける)が重要な関心事でないなら...

ドメイン駆動設計は、余計な時間と手間がかかるので、やめたほうが良いかも。

単発の受託開発プロジェクトには向かないかも。

私たちは、ビジネスの発展とともに、継続的にソフトウェアを育てていくことにこだわっている。(同じ顧客、同じ問題領域)

Page 7: ドメイン駆動設計 の 実践 Part3 DDD

DDD を現場で実践するために

Page 8: ドメイン駆動設計 の 実践 Part3 DDD

やってみせ、言って聞かせて、させてみせ、ほめてやる 業務のモデリングがそのままソフトウエアのコードになっていく過程をやってみせる

技術的な味付けで「業務モデル」の大切さを説く Domain-Driven Design アメリカの著名な技術者たちが絶賛している

Spring などメジャーなフレームワークが、DDD を指向しているので、それらを積極導入

エクセルやワードではなく、UML でドメイン層を設計させてみる コード以外の論理表現の手段に目覚めてもらう

コードのレビューで、業務の用語の理解度をチェック

Page 9: ドメイン駆動設計 の 実践 Part3 DDD

domain-model.jar

業務の知識ソフトウエアの核心

ドメインモデル中心に作る

repository.jar データベースアクセス

<<use>>

web.jar<<use>>

<<use>>

ビューとコントロール

application-service.jar<<use>>

<<use>>

業務機能(ファサード)

ソフトウェア全体が、業務のモデルを反映した構造になる。

Page 10: ドメイン駆動設計 の 実践 Part3 DDD

イベント・ソーシング 「記録」と「通知」が業務の二大関心事

業務イベントが発生したら、データベースに記録 業務イベントが発生したら、しかるべきところに通知

技術方式も、これを反映する データベース

業務イベントをデータベースに Insert オンリーで記録 「状態」は、上記のイベント記録時に更新 (トリガー) 「入庫・出庫」記録が「正」。「在庫数」は「派生データ」

非同期メッセージング 業務イベントが発生したら、非同期でメッセージ送信

データベースのトリガー+ Mule ESB のデータベースポーリング RESTスタイル API バッチ処理の激減

「予定/約束」と「リマインド/アラート」 一定期日までに、起こすべき業務イベント(予定/約束)を記録 直前にリマインドイベントを生成して、通知 期限切れは、アラートイベントを生成して、通知

Page 11: ドメイン駆動設計 の 実践 Part3 DDD

コードではなく、モデルで議論 ドメインモデル設計の関心事(業務の言葉が登場する場所)

パッケージ名 パッケージ間の依存関係 クラス名 クラス間の関連 メソッド名 オブジェクトの特定方法 (業務での識別方法/体系)

クラス図(パッケージ図)がわかりやすい コードはノイズが多い 依存関係や関連は、コードから読めない コードでは全体を俯瞰できない

ドメインモデルのクラス図とコードは、常に一致させる モデルを変更したらコードを変更する コードを変更したらモデルを変更する

Page 12: ドメイン駆動設計 の 実践 Part3 DDD

ドメインモデル設計の情報源 ドメインエキスパートとの対話

とってもたいへん

こっちがあまりにも、業務を知らなすぎる

エキスパートの頭の中を見ることはできない

基本用語は、仕込んでおく (ドメインクラス候補) 企業のホームページ

問題領域の解説本(初心者向け)

問題領域の解説本(英語→命名の元ネタ)

既存システムの画面、実データ

問題領域の基本構造 解説本の章立て → パッケージ構造

Google 検索ドメインモデルの設計パターン

Page 13: ドメイン駆動設計 の 実践 Part3 DDD

システム外部環境

利用シーン記述

業務フロー図

概念モデルの洗練

関連クラス依存クラス

ドメインモデリング中心に進める

画面・帳表ユースケース

属性追加

システム境界

ドメインモデル

イベント プロトコル

データモデル

システム価値

初期概念モデル

要求図コンテキスト図

パッケージ構造中核クラス

クラスとテーブルの設計・実装

ロバストネス図

システム (ICONIX)

シーケンス図

操作追加Java

ソースコード

基盤クラス追加

予備設計

詳細設計

ユースケースごとに開発

DDL/SQL

ソースコード

要件分析・要件定義 RDRA(リレーションシップ駆動要件定義)

Page 14: ドメイン駆動設計 の 実践 Part3 DDD

業務の知識をコードに反映する

Page 15: ドメイン駆動設計 の 実践 Part3 DDD

「業務の関心事」の分離 業務知識がUIのコードに埋もれている

画面定義(View)から業務の関心事を抽出する

コントローラから、業務ロジックをメソッドに抽出

業務ロジックを、ドメインオブジェクトに移動

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

注文

顧客名注文金額

商品数量単価金額

注文明細submit() { }

金額計算()

合計()

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

Page 16: ドメイン駆動設計 の 実践 Part3 DDD

手続型の設計(手続+データ)をドメインモデルのオブジェクトへ

注文

顧客名注文金額

商品数量単価金額

注文明細

注文

顧客名注文金額

商品数量単価金額

注文明細

金額()

税額()

合計()

税額()

Order Calculator

合計()税額算出()

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

Page 17: ドメイン駆動設計 の 実践 Part3 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 18: ドメイン駆動設計 の 実践 Part3 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 19: ドメイン駆動設計 の 実践 Part3 DDD

単なる値をドメインのオブジェクトに置き換える

class Order{

String customer;}

class Order{

Customer customer ;}

class Customer{

String name ;}

注文

String 顧客

顧客

氏名連絡先

注文

業務の重要な関心事(顧客)を記述する入れ物ができた

Page 20: ドメイン駆動設計 の 実践 Part3 DDD

業務モデルの粒度・構造と、クラスの設計を一致させる

Page 21: ドメイン駆動設計 の 実践 Part3 DDD

ゴールド会員の登録 一般会員が一定の条件をクリア

購買実績

支払事故なし

承認手続きが必要

Page 22: ドメイン駆動設計 の 実践 Part3 DDD

<<entity>>会員

会員番号氏名

ゴールド会員登録 Service

すべて情報

すべての操作

http 依存のview定義とcontrol を抽出

DBアクセスを抽出

購入履歴

支払記録

会員リポジトリ

<<entity>>ゴールド会員

会員番号氏名

<<value>>有効期限

<<value>>与信限度額

<<service>>ゴールド会員認定ポリシー

<<service>>ゴールド会員認定手続き

ゴールド会員ファクトリ

ゴールド会員リポジトリ

<<transfer>>承認依頼

<<façade>>ゴールド会員登録サービス

ドメイン層のいろんなロジック

トランザクションスクリプト?

関心事の分離変更が簡単で安全になる

ソフトウェアを育てやすい購買額が多く支払事故がない

承認が必要

Page 23: ドメイン駆動設計 の 実践 Part3 DDD

実装は必要。重要なのは、設計。

ドメイン層以外も必要。重要なのは、ドメイン層。