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