PoEAA ch9 Domain Model
An object model of the domain that incorporates both behavior and data.
- ビジネスロジックは非常に複雑になりうる
- オブジェクトのネットワークでこれを表現する
- 各オブジェクトが意味のある「個」を表現する
- 大きいものでは「企業」から
- 小さいものでは「注文」まで
- 各オブジェクトが意味のある「個」を表現する
How It Works
- オブジェクトでビジネス領域をモデリングしドメイン層をつくる
- ビジネス領域のデータを模す
- ビジネスルールをとらえる
- データと処理とを組み合わせる
- DBのスキーマと似ることがしばしば
- とはいえ違いも多い
- 「一対多」の集約
- 関連のネットワーク
- 継承
- Domain Modelの2つのスタイル
- ビジネスロジックはしょっちゅう変わる
- ドメイン層で大事なこと
- 他層との結合を最小に(疎結合に)
- 最も単純な系: ユーザが1人だけのアプリケーション
- オブジェクトグラフを単一のファイルから読み出して、全部メモリに載せることができる
- 【補】エッジとかノードとかの「グラフ」
- デスクトップアプリケーションならこれでいい
- オブジェクトグラフを単一のファイルから読み出して、全部メモリに載せることができる
- 多層アーキテクチャのIS(?)アプリケーションではそうはいかない
- 【推測】inter system もしくは inter serverかな
- オブジェクト多すぎ
- すべてのオブジェクトをメモリに載せるわけにはいかない
- メモリ消費しすぎる
- 時間かかる
- OOデータベースが輝くところ
- オブジェクトをメモリとディスクの間で直接的にやりとりできる
- OOデータベースを使わない場合、メモリ-ディスク間のオブジェクトのやりとりを自前で取り回さないといけない
- セッションに絡む、必要なオブジェクトグラフを読み出す
- 何をメモリに載せるかはO/Rマッピングオブジェクトに依存する
- セッションに絡む、必要なオブジェクトグラフを読み出す
- サーバ間で同一のオブジェクトグラフが必要な場合
- サーバのステートをどこかに保存する必要がある
- ドメインオブジェクト肥大化問題について
- 特定のユースケース固有の振る舞いの責務は誰が持つ
- Domain Model?
- もっと上の層?(usage-specific class)
- 特定のユースケース固有の振る舞いの責務は誰が持つ
- usage-specific classの問題点
- コードの多重化を引き起こしやすい
- Domain Modelから離れた場所に実装されるので、すでにあるものを見つけづらい
- 多重化したが最後
- 複雑化
- 一貫性を失う
- コードの多重化を引き起こしやすい
- Domain Modelの肥大化のほうがマシ
- 肥大化自体そうそう起きない
- 起きたとして、コードの多重化よりも見つけやすく修正しやすい
- usage-specific classは切り出さないほうがいい
- それでDomain Modelが肥大化してしまったら、そのとき考えれば良い
Java Implementation
- J2EEでDomain Modelを開発するとなると、議論は白熱する
- J2EEの入門本「Entity Beans使え」
- バージョン2.0時点では問題がある
- リッチなDomain Modelを作る上で大きな制約がある
- CMP: Container Managed Persistenceの制限
- 簡素なO/Rマッパー
- Entity Beansは、CMPと一緒に使うと力を発揮する
- リッチなDomain Modelを作るのはきつい
- Entity Beansはre-entrantであるべきではない
- 【補】循環参照のこと
- OOPのアドバンテージ損なう
- 【補】Strategy Patternとか書く時困るよね
- CMP: Container Managed Persistenceの制限
- Domain ModelでEntity Beansを使用する場合はローカルインタフェース使え
- Domain Modelを作る上ではfine-grainedなインタフェースが要請される
- Entity Beansはリモートアクセス可能
- fine-grainedなインタフェースでリモートアクセスすると深刻なパフォーマンス劣化をもたらしうる
- ビルドやテストに時間がかかる・テスト大変
- コンテナとDBを接続する必要があるため
- じゃあどうする
- POJO: Plain Old Java ObjectをEJBコンテナでくるむ
- ドメインロジックの複雑性がほどほどならEntity Beansでうまくいくだろう
- 1 beanクラス1テーブルくらいの単純さ
- 複雑ならPOJO + Data Mapper使え
- OOPのパターンをいろいろ使ったリッチなDomain Modelが必要
When to Use It
- ドメインロジックが複雑なとき
- ビジネスルールが絶えず変化する
- バリデーション
- 計算
- 導出
- 【補】導出: 面積=幅x高さ とかそういうやつ
- 「nullチェックと総和計算」程度ならTransaction Scriptがいいだろう
- ビジネスルールが絶えず変化する
- チームがOOPにどれくらい慣れ親しんでいるかも重要
- 一度慣れればTransaction Scriptに戻りたくなくなる
- 著者はドメイン層にDomain Modelを採用したら、データソース層にはまずData Mapperを検討する
- Domain ModelとDBのスキーマとが非依存になる
- Service Layerを追加することで別個のAPIをもたせることもできる
- しないこともできる
Further Reading
- OO設計
- Larman
- Domain Modelの例
- Fowler AP
- Hay
- conceptual thinking about objects
- Martin and Odell
- デザパタ
- DDD
- Evans
Example: Revenue Recognition (Java)
- コード略(pp.120-123)
- Strategy Patternとか使って条件分岐自体をなくせるよ
- 新しい収益認識方法が追加されたら、同じインタフェースをもつ新しいクラスを追加するだけでいい