Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

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

8,203 views

Published on

2011/6/20 redajp

Published in: Technology

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

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

×