ドメインロジックの実装方法とドメイン駆動設計

17,164 views

Published on

Published in: Technology

ドメインロジックの実装方法とドメイン駆動設計

  1. 1. ドメインロジックの実装方法と ドメイン駆動設計 Ouobpo 佐藤 匡剛 http://ameblo.jp/ouobpo BPStudy 第 7 回 2008 年 3 月 28 日
  2. 2. もくじ <ul><li>第Ⅰ部 ドメインロジックの実装方法 </li></ul><ul><li>第Ⅱ部 ドメイン駆動設計の紹介 </li></ul>
  3. 3. 第Ⅰ部 ドメインロジックの実装方法
  4. 4. 3 層アーキテクチャ <ul><li>エンタープライズアプリの典型的アーキテクチャ </li></ul>Web アプリ FW サービスレイヤー DI / IoC コンテナ データアクセス FW DAO プレゼンテーション層 ドメイン層 インテグレーション層 POJO アクション アクション アクション POJO POJO POJO DAO インテグレーション ゲートウェイ システム間統合 MW FW ・・・ フレームワーク   MW ・・・ ミドルウェア ルールエンジン ワークフローエンジン
  5. 5. ビジネスにとって最も重要な部分 Web アプリ FW サービスレイヤー DI / IoC コンテナ データアクセス FW DAO プレゼンテーション層 ドメイン層 インテグレーション層 POJO アクション アクション アクション POJO POJO POJO DAO インテグレーション ゲートウェイ システム間統合 MW ルールエンジン ワークフローエンジン 業務知識を実現している部分=ドメインロジック
  6. 6. ドメインロジック実装の 3 つのパターン Martin Fowler 『エンタープライズアプリケーションアーキテクチャパターン』より) <ul><li>Transaction Script パターン </li></ul><ul><ul><li>ドメインロジックをデータと振舞に分け、振舞をスクリプト的に記述する方法。手続き的。 </li></ul></ul><ul><li>Domain Model パターン </li></ul><ul><ul><li>ドメインロジックをデータと振舞を合わせたオブジェクトによりモデル化する方法。オブジェクト指向的。 </li></ul></ul><ul><li>Table Module パターン </li></ul><ul><ul><li>上記 2 つの中間的な方法。データと振舞を分けるが、振舞をテーブル毎に構成する。(今回は省略) </li></ul></ul>
  7. 7. Transaction Script パターン ( Martin Fowler 『エンタープライズアプリケーションアーキテクチャパターン』より)
  8. 8. Domain Model パターン ( Martin Fowler 『エンタープライズアプリケーションアーキテクチャパターン』より)
  9. 9. Transaction Script と Domain Model の比較 <ul><li>Transaction Script </li></ul><ul><ul><li>○ 構造がシンプル。 OO に慣れてないプログラマにも分かりやすい </li></ul></ul><ul><ul><li>× ロジックが複雑になると重複がひどくなる </li></ul></ul><ul><li>Domain Model </li></ul><ul><ul><li>○ 複雑なロジックも重複なくきれいにモデル化できる </li></ul></ul><ul><ul><li>× 非常にハードルが高い。データベースとのマッピングも大変 </li></ul></ul>
  10. 10. 日本では・・・ <ul><li>Transaction Script が主流 </li></ul><ul><ul><li>Domain Model を採用したプロジェクトは見たことがない </li></ul></ul><ul><ul><li>⇒  なぜ? </li></ul></ul><ul><li>ちまたに Domain Model のサンプルコードがほとんどないからでは? </li></ul><ul><ul><li>PofEAA もちょっとしかサンプルコードを載せていない </li></ul></ul><ul><ul><li>雑誌でも Domain Model のサンプルコードはほとんどない </li></ul></ul><ul><ul><li>フレームワーク、 DI コンテナに付いてくるサンプルコードはだいたい Transaction Script 寄り </li></ul></ul><ul><li>⇒  それではサンプルコードを見てみよう! </li></ul>
  11. 11. 給与計算システムの例 ユースケース図
  12. 12. 給与システムのドメインモデル
  13. 13. 給与システムのデータモデル
  14. 14. 給与システムのサンプルコード <ul><li>Google Code プロジェクトの SVN リポジトリ上に公開されています。 </li></ul><ul><ul><li>http:// ouobpo.googlecode.com/svn/trunk/   bpstudy-200803/ </li></ul></ul>
  15. 15. Transaction Script 版の設計クラス図
  16. 16. Domain Model 版の設計クラス図
  17. 17. Domain Model パターンの真のメリット① <ul><li>複雑なロジックを可視化できる </li></ul>【 Transaction Script 】 【 Domain Model 】 文章で書かれた仕様がそのままソースコードに 設計クラス図 ? ソースコードの構造が分かる .xls ユースケース記述 ビジネスルール定義書 ソースコード .xls ユースケース記述 ビジネスルール定義書 ソースコード
  18. 18. Domain Model パターンの真のメリット② <ul><li>ソースコードそのものはシンプルになる </li></ul><ul><ul><li>クラス/インタフェースの数が減る </li></ul></ul><ul><ul><ul><li>Logic + Entity ⇒ DomainObject </li></ul></ul></ul><ul><ul><li>メソッドの引数が減る </li></ul></ul><ul><ul><ul><li>pay(employee, year, month) ⇒ pay(year, month) </li></ul></ul></ul><ul><ul><li>メソッド内の Getter メソッド呼び出しが減る </li></ul></ul><ul><ul><ul><li>entity.getXxx() ⇒ this.xxx </li></ul></ul></ul><ul><ul><li>Getter / Setter メソッドが減る </li></ul></ul>
  19. 19. Domain Model を採用する際の障壁 <ul><li>3 つの障壁 </li></ul><ul><ul><li>Domain Model は修得が難しく、開発者の確保が難しい </li></ul></ul><ul><ul><ul><li>OO 的な考え方の普及、技術者の底上げが必要 </li></ul></ul></ul><ul><ul><ul><li>そもそも高度な専門分野なのに、ソフトウェア工学の学位をもった技術者がほとんどいないという、日本の IT 業界の構造的な問題? </li></ul></ul></ul><ul><ul><li>DI との親和性が低い </li></ul></ul><ul><ul><ul><li>確かに Seasar の SMART デプロイ、 S2Dao とは相性が悪い </li></ul></ul></ul><ul><ul><ul><li>DI コンテナ、フレームワーク側が頑張ればなんとかなるのでは? </li></ul></ul></ul><ul><ul><li>日本のビジネスはデータと振舞を分けた方が自然にモデル化できる、という意見 </li></ul></ul><ul><ul><ul><li>たまたまそういう仕事が今 SI 業界で多いだけはないか? </li></ul></ul></ul><ul><ul><ul><li>プロセス重視のドメイン(財務シミュレーション、生産ライン管理、給与計算など)でデータと振舞を分けるメリットはあるのか? </li></ul></ul></ul>
  20. 20. Domain Model の作り方 (作り方が分からないという方のために) <ul><li>GRASP パターン( Craig Larman 『実践 UML 』) </li></ul><ul><ul><li>情報エキスパート( Information Expert ) </li></ul></ul><ul><ul><li>生成者( Creator ) </li></ul></ul><ul><ul><li>コントローラ( Controller ) </li></ul></ul><ul><ul><li>低結合性( Low Coupling ) </li></ul></ul><ul><ul><li>高凝集性( High Cohesion ) </li></ul></ul><ul><ul><li>多相性( Polymorphism ) </li></ul></ul><ul><ul><li>でっち上げ( Pure Fabrication ) </li></ul></ul><ul><ul><li>間接化( Indirection ) </li></ul></ul><ul><ul><li>バリエーション防護( Protected Variations ) </li></ul></ul>この辺がとくに重要!
  21. 21. とはいえ、そんなに複雑なビジネスロジックってあるの? <ul><li>最近の Web アプリケーションは、ほとんどが CRUD 処理のみ </li></ul><ul><ul><li>「ドメインロジック層なんていらないじゃん」 </li></ul></ul><ul><ul><li>画面や DB から直接作ってしまった方がいいのでは? </li></ul></ul><ul><li>すべてをリッチにドメインモデリングする必要はない </li></ul><ul><ul><li>私の経験だと、ロジックが複雑な部分はアプリ全体の 10% くらい </li></ul></ul><ul><ul><li>ビジネス的に重要な部分(=ロジックが複雑な部分)だけ、優秀なリソースを投入してきちんとモデリングすればいい </li></ul></ul><ul><ul><li>ロジックの薄い部分は手間を掛けず、ローコストに瞬殺する </li></ul></ul><ul><ul><ul><li>Transaction Script なり Active Record なりを使う </li></ul></ul></ul><ul><ul><ul><li>外注する </li></ul></ul></ul><ul><ul><ul><li>パッケージ製品を買ってきて作らずに済ます </li></ul></ul></ul>
  22. 22. とはいえ、そんなに複雑なビジネスロジックってあるの? (つづき) <ul><li>そもそもシステムが頭を使っていないからではないか? </li></ul><ul><ul><li>Web CRUD なアプリは、結局オペレータが頭を使っている </li></ul></ul><ul><ul><li>戦略的なシステムは、もっと頭を使うはず </li></ul></ul><ul><li>ドメインリッチなシステムは省人化を進める </li></ul><ul><ul><li>今まで人間がやっていた業務をシステムが肩代わりする </li></ul></ul><ul><ul><li>会社の最適化に貢献するが、従業員削減にもつながってしまう </li></ul></ul><ul><ul><ul><li>従業員からすると好ましくないシステム </li></ul></ul></ul><ul><ul><ul><li>強い権限をもつ CIO がトップダウンにやらないと難しい </li></ul></ul></ul><ul><ul><li>リストラが当たり前の欧米(?)でドメインモデルが流行って、日本でなかなか流行らない理由の 1 つ? </li></ul></ul>
  23. 23. 余談
  24. 24. DAO と O/R マッパの違い <ul><li>DAO </li></ul><ul><ul><li>ロジックに対して DB ゲートウェイの役割をするもの </li></ul></ul><ul><ul><li>ロジックが DAO を呼び出す </li></ul></ul><ul><li>O/R マッパ </li></ul><ul><ul><li>ドメインオブジェクトと DB とをマッピングするもの </li></ul></ul><ul><ul><li>ドメインオブジェクトは O/R マッパと DB の存在を知らなくていい </li></ul></ul>
  25. 25. Hibernate / JPA の間違った使い方 <ul><li>Hibernate / JPA は、本来 O/R マッパ </li></ul><ul><li>なのに、 DAO の実装に使ってしまうことがよくある </li></ul>
  26. 26. 第Ⅱ部 ドメイン駆動設計の紹介
  27. 27. 『 Domain-Driven Design 』( Eric Evans 著) <ul><li>一冊まるまる「ドメインモデリング」について扱った書籍 </li></ul><ul><ul><li>「ソフトウェアの真の複雑さに挑戦する」 </li></ul></ul><ul><li>パターン本の 1 つ </li></ul><ul><ul><li>40 パターン+ 1 アンチパターン </li></ul></ul><ul><li>海外では大ブームに </li></ul><ul><ul><li>Ralph Johnson ( GoF の 1 人): 「 4 、 5 回は読み直した」 </li></ul></ul><ul><ul><li>Rod Johnson ( Spring 創始者): 「 Java 開発のこれからはリッチドメインモデルだ」 </li></ul></ul>
  28. 28. ドメイン駆動設計とはなにか <ul><li>ドメインモデルを中心にすえた設計思想 </li></ul><ul><ul><li>ドメインモデルはドメイン知識を深めながら反復的( iterative )に設計していく </li></ul></ul><ul><ul><li>ドメインモデルを開発者とユーザ・専門家の間の共通言語に </li></ul></ul><ul><ul><li>ドメインモデル⇔実装コード(や他の成果物)の対応関係を最後まで維持する </li></ul></ul>
  29. 29. DDD 本の構成 <ul><li>DDD の基本思想 </li></ul><ul><ul><li>DDD の基本的な考え方や前提 </li></ul></ul><ul><li>モデル駆動設計( MDD )の構成要素 </li></ul><ul><ul><li>MDD を実現する OO ベストプラクティス。既にあるドメインモデルをいかにソフトウェア設計に落とし込むか </li></ul></ul><ul><li>ドメインリファクタリング </li></ul><ul><ul><li>ドメインモデルにドメイン知識を反映させ、より深いモデルにしていくためのノウハウ </li></ul></ul><ul><li>戦略的デザイン </li></ul><ul><ul><li>1 アプリの範囲を超えて、大規模開発/ SOA に DDD を適用していく方法 </li></ul></ul>
  30. 30. MDD 実践的 モデラー ユビキタス 言語 DDD の基本思想 基本要素 ライフサイクル 深いモデル + しなやかな設計 制約 プロセス 仕様 抽象化 分割 コンテキスト マッピング ドメインの 優先付け 「大きな絵」 の共有 MDD の構成要素 ドメインリファクタリング 戦略的デザイン 単一アプリケーションの開発 大規模開発/ SOA エンティティ 値 サービス モジュール 集約 ファクトリ リポジトリ 中核ドメイン 汎用サブ ドメイン コンテキスト マップ 継続的 統合 メタファ 責務の 階層
  31. 31. Ⅰ . DDD の基本思想 <ul><li>ドメインモデルを、プロジェクトを駆動する 「共通言語」 にすること </li></ul><ul><li>DDD の基本三原則 </li></ul><ul><ul><li>Ubiquitous Language (ユビキタス言語)パターン </li></ul></ul><ul><ul><li>Model-Driven Design (モデル駆動設計)パターン </li></ul></ul><ul><ul><li>Hands-On Modeler (実践的モデラー)パターン </li></ul></ul>
  32. 32. Ⅱ . MDD の構成要素 <ul><li>これまでの OO 方法論の集大成 </li></ul><ul><ul><li>責務駆動設計( Responsibility-Driven Design ) </li></ul></ul><ul><ul><li>契約による設計( Design by Contract ) </li></ul></ul><ul><ul><li>GRASP パターン </li></ul></ul><ul><ul><li>エンタープライズアプリケーションアーキテクチャパターン </li></ul></ul>
  33. 33. MDD を構成するパターン <ul><li>まずドメイン層を分離する </li></ul><ul><ul><li>Layered Architecture (層状アーキテクチャ)パターン </li></ul></ul><ul><ul><li>Smart UI (利口な UI )アンチパターン </li></ul></ul><ul><li>ソフトウェアによってモデルを表現する </li></ul><ul><ul><li>Entities (エンティティ)パターン </li></ul></ul><ul><ul><li>Value Objects (値オブジェクト)パターン </li></ul></ul><ul><ul><li>Services (サービス)パターン </li></ul></ul><ul><ul><li>Modules (モジュール)パターン </li></ul></ul>
  34. 34. MDD を構成するパターン(つづき) <ul><li>ドメインオブジェクトのライフサイクルを設計する </li></ul><ul><ul><li>Aggregates (集約)パターン </li></ul></ul><ul><ul><li>Factories (ファクトリ)パターン </li></ul></ul><ul><ul><li>Repositories (リポジトリ)パターン </li></ul></ul>
  35. 35. Ⅲ . ドメインリファクタリング <ul><li>現実のドメインモデリングは古典的 OO 方法論が教えるほど単純ではない </li></ul><ul><ul><li>( × )「名詞をクラスにして、動詞をメソッドにする」 </li></ul></ul><ul><ul><li>反復的にモデルを深めていく必要がある </li></ul></ul><ul><li>リファクタリングの 3 つのレベル </li></ul><ul><ul><li>マイクロリファクタリング </li></ul></ul><ul><ul><li>パターン指向リファクタリング </li></ul></ul><ul><ul><li>ドメインリファクタリング </li></ul></ul><ul><li>ドメインリファクタリングの 2 つの柱 </li></ul><ul><ul><li>深いモデル( deep model ) </li></ul></ul><ul><ul><li>しなやかな設計( supple design ) </li></ul></ul>
  36. 36. 深いモデル <ul><li>隠れた概念を発掘する </li></ul><ul><ul><li>見つけづらい概念には、以下がある </li></ul></ul><ul><ul><ul><li>制約 </li></ul></ul></ul><ul><ul><ul><li>プロセス </li></ul></ul></ul><ul><ul><ul><li>仕様 </li></ul></ul></ul><ul><ul><li>Specifications (仕様)パターン </li></ul></ul>
  37. 37. しなやかな設計 <ul><li>理解を容易にする抽象化 </li></ul><ul><ul><li>Intention-Revealing Interfaces (意図の明白なインタフェース)パターン </li></ul></ul><ul><ul><li>Side-Effect-Free Functions (副作用のない関数)パターン </li></ul></ul><ul><ul><li>Assertions (表明)パターン </li></ul></ul><ul><li>変更しやすい適切な分割 </li></ul><ul><ul><li>Conceptual Contours (概念の輪郭)パターン </li></ul></ul><ul><ul><li>Standalone Classes (独立したクラス群)パターン </li></ul></ul><ul><ul><li>Closures of Operations (閉じた操作)パターン </li></ul></ul>
  38. 38. Ⅳ . 戦略的デザイン <ul><li>単一アプリの枠組みを超えたシステム構築 </li></ul><ul><ul><li>大規模開発や EAI 、 SOA の世界 </li></ul></ul><ul><ul><li>企業情報システムの全体構造( EA )に深く関係する </li></ul></ul><ul><ul><li>経営戦略的( strategic )な視点が求められる </li></ul></ul><ul><li>全企業的な視野においても、ドメインを深く反映したシステムこそが大きなビジネス価値につながる </li></ul><ul><li>「戦略的デザイン」の構成 </li></ul><ul><ul><li>コンテキスト( context ) </li></ul></ul><ul><ul><li>蒸留( distillation ) </li></ul></ul><ul><ul><li>大規模な構造( large-scale structure ) </li></ul></ul>
  39. 39. コンテキスト-他システムとの統合 <ul><li>システム統合における課題 </li></ul><ul><ul><li>異なるドメインモデル間の不整合をいかに解決するか </li></ul></ul><ul><li>コンテキストの境界を定める </li></ul><ul><ul><li>Bounded Context (コンテキスト境界)パターン </li></ul></ul><ul><ul><li>Continuous Integration (継続的な統合)パターン </li></ul></ul><ul><ul><li>Context Map (コンテキストマップ)パターン </li></ul></ul>
  40. 40. コンテキスト-他システムとの統合 (つづき) <ul><li>コンテキスト間の 6 つの関係 </li></ul><ul><ul><li>Shared Kernel (共有カーネル)パターン </li></ul></ul><ul><ul><li>Customer/Supplier Development Teams (顧客/供給者の開発チーム)パターン </li></ul></ul><ul><ul><li>Conformist (順応者)パターン </li></ul></ul><ul><ul><li>Anticorruption Layer (腐敗防止層)パターン </li></ul></ul><ul><ul><li>Separate Ways (別々の道)パターン </li></ul></ul><ul><ul><li>Open Host Service (公開ホストサービス)パターン </li></ul></ul>
  41. 41. コンテキスト-他システムとの統合 (つづき) <ul><li>補足的なパターン </li></ul><ul><ul><li>Published Language (公表された言語)パターン </li></ul></ul>
  42. 42. 蒸留-戦略的な優先付け <ul><li>企業のコアコンピタンス(競争力)をいかに向上させるか </li></ul><ul><ul><li>限りあるリソースをどこに投入するかが大きな課題 </li></ul></ul><ul><li>ドメインの優先順位付け </li></ul><ul><ul><li>Core Domain (中核ドメイン)パターン </li></ul></ul><ul><ul><li>Generic Subdomains (汎用サブドメイン)パターン </li></ul></ul>
  43. 43. 蒸留-戦略的な優先付け(つづき) <ul><li>中核ドメインの文書化方法 </li></ul><ul><ul><li>Domain Vision Statement (ドメインビジョン説明書)パターン </li></ul></ul><ul><ul><li>Highlighted Core (中核のハイライト)パターン </li></ul></ul><ul><li>中核をさらに中核らしく磨き上げる </li></ul><ul><ul><li>Cohesive Mechanisms (凝集されたメカニズム)パターン </li></ul></ul><ul><ul><li>Segregated Core (中核の隔離)パターン </li></ul></ul><ul><ul><li>Abstract Core (中核の抽象化)パターン </li></ul></ul>
  44. 44. 大規模な構造-「大きな絵」の共有 <ul><li>大規模システムの開発をいかに成功させるか </li></ul><ul><ul><li>チームがアーキテクチャレベルの「大きな絵」を共有し、同じ目標意識をもって協調することが肝心 </li></ul></ul><ul><li>大規模な構造を扱う際の基本姿勢 </li></ul><ul><ul><li>Evolving Order (進化則)パターン </li></ul></ul>
  45. 45. 大規模な構造-「大きな絵」の共有 (つづき) <ul><li>大規模な構造の 3 つのパターン </li></ul><ul><ul><li>System Metaphor (システムのメタファ)パターン </li></ul></ul><ul><ul><li>Responsibility Layers (責務の階層構造)パターン </li></ul></ul><ul><ul><li>Knowledge Level (知識レベル)パターン </li></ul></ul><ul><li>幸福な DDD の最終形態 </li></ul><ul><ul><li>Pluggable Component Framework (可換コンポーネントフレームワーク)パターン </li></ul></ul>
  46. 46. 最後に
  47. 47. なぜドメインモデルなのか? <ul><li>それはドメインモデルが楽しいから! </li></ul><ul><ul><li>(がんばれば)複雑なシステムでもきれいに構築可能 </li></ul></ul><ul><ul><li>オブジェクトという部品を使ってモノづくりする楽しさ </li></ul></ul><ul><ul><li>自分が作ったシステムの形を視覚的に実感できる </li></ul></ul><ul><ul><li>トランザクションスクリプトより、なんか作ってて楽しい </li></ul></ul><ul><li>結局、 Ruby でプログラミングするのがなぜか楽しいのと同じことでは? </li></ul>
  48. 48. ドメインモデル作りを 楽しみましょう!

×