Martin FowlerのPatterns of Enterprise Application ArchitectureすなわちPoEAA、何年か前に原著をKindleで買って読もうとして序盤で挫折していた。最近またデータソースアーキテクチャについて翻訳版と原著を合わせて読んでいるので、整理のためメモを残しておく。
パターン
本書で紹介されるパターンはアプリケーションアーキテクチャから通貨の値オブジェクトまで、粒度もレイヤーも様々。今回はデータソースアーキテクチャパターンを理解するのに必要な箇所だけ調べた。
ドメインロジックパターン
- トランザクションスクリプト
- ほとんど構造化されてない書き下しなロジックのこと。ちょろいスクリプトならこれでもいいけど、ちょっと複雑になるとすぐに破綻する。
- ドメインモデル
- 業務上の概念をオブジェクト化して、それらを組み合わせて複雑なロジックを構成する。
データマッパー
、サービスレイヤー
パターンと組み合わせると良い。
- 業務上の概念をオブジェクト化して、それらを組み合わせて複雑なロジックを構成する。
- テーブルモジュール
- サービスレイヤ -
- 「複数リソースにまたがるトランザクションやアクションに対する複数のレスポンスの調整」などの相互作用をハンドリングするためのレイヤー。アクターからみたUIに相当。
- PofEAA's Wiki - ServiceLayer の図を参照。
- 依存の方向が外側のレイヤーからアプリケーション -> サービスレイヤー -> ドメインモデル -> データソースレイヤー
- 実装手法
データソースアーキテクチャパターン
データベース操作のSQLとアプリケーションロジックの分離の仕方、ModelがControllerとデータベースの変換をどう扱うのかという話題。
テーブルデータゲートウェイ
行データゲートウェイ
アクティブレコード
データマッパー
の4パターンが紹介されている。
テーブルデータゲートウェイ
- ひとつのデータベーステーブルがひとつのオブジェクトインスタンスになる
ゲートウェイ
。テーブルへの操作(find,update,insert,delete)を備える。 Record Set
(ジェネリックなデータ構造)やTable Module
パターンとの併用に適している。- データベースの戻り値の
Record Set
を返してもいいし、ドメインオブジェクトにマッピングして返してもいい。Record Set
を返してデータ変換オブジェクト
を用いれば、ユーザーが好きな方を選べて良いのではないか ドメインモデル
を使っている場合、テーブルデータゲートウェイ
はドメインオブジェクトを返せるが、双方向の依存性が発生するのであんまり良くないテーブルモジュール
例
// この例ではFindメソッドの戻り値にジェネリックなRecordSetを返却しているが、上の議論のように別にPersonオブジェクトを返しても問題はない。 class PersonGateway { Find(id): RecordSet FindWithLastNames(String): RecordSet Update(id, lastname,firstname, numberOfDependents) Insert(lastname, firstname, numberObDependents) Delete(id) } ... RecordSet r = personGateway.Find(1) printf( r.Column("lastName") ) personGateway.Insert(2,"John","Doe",3) personGateway.Update(2,"John","Doe",4) personGateway.Delete(2)
行データゲートウェイ
- クエリ結果の行ひとつひとつがオブジェクトのインスタンスになる。ドメインオブジェクトが
p.update()
とか振る舞うのでオブジェクト指向感がある。 - でもインメモリのオブジェクトにデータベースのアクセスコードが仕込まれる必要があるので、データベースとオブジェクトが密に結合してテストがやりにくかったりするデメリットがある。
- トランザクションスクリプトに最適。
- Findの動作をどこに定義するのかが問題になりがち
行データゲートウェイ
に含まれるのはデータベースアクセスロジックだけ。ドメインロジックが含まれたらアクティブレコード
パターンに進化する。
例
//static Findメソッドは別クラス(e.g. PersonFinder)に実装してもよい class PersonGateway{ lastname firstname numberOfDependents static Find(id): PersonGateway static FindWithLastName(String): PersonGateway[] insert() update() delete() } ... p1 = new PersonGateway() p1.firstname = "John" p1.lastname = "Doe" p1.insert() p = PersonGateway.Find(2) p.numberOfDependents = 10 p.update() p.delete()
アクティブレコード
行データゲートウェイ
のクラスにドメインロジックを追加したようなもの。行データゲートウェイ
やテーブルデータゲートウェイ
はドメインモデル
とあまり相性が良くない。ドメインモデル
であればアクティブレコード
が向いてる(複雑なものでなければ)。アクティブレコード
クラスは以下のメソッドを持つ- フィールドの型はテーブル内の各列と一致しなければならない。get/set時に他の効率のよい型への変換が認められる。
- findメソッドは多くの場合静的に実装されるが、別に独立したクラスに分離してもよい。(テストもそのほうがしやすい)
例
class PersonGateway{ lastname firstname numberOfDependents static find(id): PersonGateway static findWithLastName(String): PersonGateway[] insert() update() delete() getExemption() isFlaggedForAudit() getTaxableEarnings() }
データマッパー
オブジェクトとデータベーステーブルは所詮別物(継承、コレクション、Joinの有無など)なので、1:1の対応でハンドリングするには限界がある。両者を変換するマッパがあれば複雑なドメインロジックと複雑なデータベーステーブルをハンドル出来るよ、的なパターン。
データマッパー
はドメインオブジェクトとデータベーステーブルの間のデータの受け渡し(ロード/ストア)を責務とするソフトウェアレイヤ。ドメインモデルとデータベースを完全に分離し独立を保つ。ドメインオブジェクトはデータベースについて一切関知しなくてよくなる。- 全てのDB通信とマッピングを
データマッパー
が担うため、DBスキーマ、ドメインオブジェクトそれぞれ独立して設計・開発が進められるメリット。 - データマッパーがゲートウェイをラップすることはあり得る
- 本書で紹介される「オブジェクトリレーショナルマッピングパターン」は、全て
データマッパー
でオブジェクトとテーブルを接合させるためのストラテジ
例
class PersonMapper{ insert(Person) update(Person) delete(Person) } class Person{ lastName firstName numberOfDependents getExemption() isFlaggedForAudit() getTaxableEarnings() }
データソースレイヤーアーキテクチャパターンの選び方
この本によると
関連する基本パターン ゲートウェイ
とマッパー
の違い
ゲートウェイとマッパーはともに、ドメインオブジェクトと外部サービス(データベースなど)のインターフェイスとなる似たパターンだが、依存の方向性が逆方向になる。
ゲートウェイ
- 外部サービスをラッピングして他のドメインオブジェクトが簡単に使えるようにする。
- テストのためのサービススタブや、将来的に他のサービスに切り替えるためのポイントにもなる。間接化によって柔軟性を提供する。
- PofEAA's Wiki - Gateway
マッパー
- サブシステム間の通信を取り持つ分離レイヤー。サブシステム間の相互作用をハンドリングする。
- PofEAA's Wiki - Mapper
- 図のように、 マッパーが全ての関連サブシステムに依存している。サブシステムからマッパーへの依存はない。
その他のパターン
(今回は調べてない)
- オブジェクトリレーショナル振る舞いパターン
- オブジェクトリレーショナル構造パターン
- オブジェクトリレーショナルメタデータマッピングパターン
- Webプレゼンテーションパターン
- 分散パターン
- オフライン平行性パターン
- セッションステートパターン
- 基本パターン
エンタープライズ アプリケーションアーキテクチャパターン (Object Oriented Selection)
- 作者: マーチン・ファウラー,長瀬嘉秀,株式会社テクノロジックアート
- 出版社/メーカー: 翔泳社
- 発売日: 2005/04/21
- メディア: 単行本
- 購入: 10人 クリック: 635回
- この商品を含むブログ (142件) を見る
Patterns of Enterprise Application Architecture
- 作者: Martin Fowler
- 出版社/メーカー: Addison-Wesley Professional
- 発売日: 2002/11/05
- メディア: Kindle版
- この商品を含むブログを見る