Active Record
An object that wraps a row in a database table or view,
encapulates the database access, and adds domain logic on that data.
How It Works
- Active RecordはDBアクセスとドメインロジックの責務を有する
-
どれくらいドメインロジック持つ?
- ぜんぶ
-
共通でデータ指向な部分のみ
- そうでない部分はTransaction Scriptにもたせる
- クラスのフィールドとテーブルのカラムが一致すること
-
テーブルに限らずビューでもいい
- UPDATE大変
-
Active Recordクラスが有するメソッド
- SQL結果からActive Record生成
- 表へのINSERTからActive Record生成
- staticなfinderメソッド
- Active Recordが保持しているデータでUPDATE/INSERT
- getter/setter
- ドメインロジック
- getter/setter: SQLの型ではなく、使用している言語の型
-
関連する表のActive Recordを返すgetterもありうる
- 【補】外部キーで参照してコレクション得るとかそういうの
- 【補】LaravelのEloquentのリレーション
-
RDBの存在は一切隠蔽されない
- 【訳が怪しい】他のパターンよりもクラス数少ない?
-
Row Data Gatewayとどう違うの
- Row Data GatewayはDBアクセスのみ
- Active Recordはドメインロジック含む
- 線引きはわりとあいまい
- DBと密結合していることもあり、staticなfinderメソッドが生やされるのをよく見る
-
Row Data Gatewayよろしく、Finderクラスを作ってもよい
- テスト容易性にすぐれる
When To Use It
-
ドメインロジックがさほど複雑でない場合
- CRUD
-
導出やバリデーションも単一レコード単位
- 【補】導出: 面積=幅x高さ とかそういうやつ
- ドメイン層にDomain Modelを採用した場合、データソース層の選択はおもに2つ
Active Record | Data Mapper | |
---|---|---|
メリット | シンプル | 複雑 |
デメリット | DBのスキーマに引きずられる | 複雑なマッピングできる |
- Active Recordはオブジェクト設計とDB設計とを結合させてしまうのでリファクタが大変、という指摘もある
-
ドメイン層にTransaction Script採用時に、多重化したコードを繰り出すのに使うのは良い
- まずDBをRow Data Gatewayでラップする
- 振る舞いを移植する
- ちょっとずつActive Recordになる
Example: A Simple Person (Java)
- ほぼ略
-
Derivation(導出)をもたせたりする(=ドメインロジック)
- UMLのクラス図でいうところの
/
で始まるフィールド
- UMLのクラス図でいうところの
class Person...
public Money getExemption() {
Money baseExemption = Money.dollars(1500);
Money dependentExemption = Money.dollars(750);
return baseExemption.add(dependentExemption.multiply(this.getNumberOfDependents()));
}
-
number_of_dependents
カラムから税控除(exemption
)を導出している- 税控除の算出方法はドメインロジック
英語
-
exemption
- 税控除