PoEAA ch12 Inheritance Mappers
Inheritance Mappers
A structure to organize database mappers that handle inheritance hierarchys.
@startuml abstract class Mapper { + insert(DomainObject) + update(DomainObject) + delete(DomainObject) # save(DomainObject, Row) # load(DomainObject, Row) } abstract class AbstractPlayerMapper{ # save() # load() } class PlayerMapper{ + find(key):Player + insert() + update() } class FootballerMapper{ + find(key):Footballer # save() # load() } class CricketerMapper{ + find(key):Cricketer # save() # load() } class BowlerMapper{ + find(key):Bowler # save() # load() } Mapper <|-down- PlayerMapper Mapper <|-right- AbstractPlayerMapper CricketerMapper -up-|> AbstractPlayerMapper FootballerMapper -up-|> AbstractPlayerMapper BowlerMapper -up-|> CricketerMapper PlayerMapper *-right-> "1" FootballerMapper PlayerMapper *-right-> "1" CricketerMapper PlayerMapper *-right-> "1" BowlerMapper @enduml
- DBの保存・読み出しのコード記述量を最少にする
- 共通処理を基底Mapperに
- 【補】 Template Method Pattern的な思想
- 振る舞いの詳細はTable Inheritance系パターンとして何を採用するかにより異なる
- Single Table Inheritance
- Class Table Inheritance
- Concrete Table Inheritance
- Inheritance Mappersの構造自体は同じ
How It Works
- DomainModel具象クラスごとに具象Mapperを作る
- DomainModelのクラス階層と対応
- FootballMapper
- CricketMapper
- BowlerMapper
- 【補】AbstractPlayerMapperは処理共通化のための基底クラス
- 機能追加・修正時、変更点は1個所
- DomainModelのクラス階層と対応
- 具象Mapperを束ねるMapperを作る
- DomainModelのクラス階層の外
- PlayerMapper
- 【補】Composite Pattern
- DomainModelのクラス階層の外
- 具象Mapperの
find(key)
メソッドの戻り値の型- 静的型付け言語の多くでは、オーバライドした関数の戻り値の型を変ることはできない
- 【補】PHP7.2新機能: パラメータの反変性・戻り値の共変性
- 静的型付け言語じゃないけど近づこうという動きの中で生まれた
- 派生型では...
- 引数は拡大していい(タイプヒント有 -> 無)
- 戻り値は縮小していい(タイプヒント無 -> 有)
- が、タイプヒントの変更はできないはず
- 抽象型を返すのはNG
- 呼び出し側でダウンキャストをしないといけない
- 動的型付け言語では問題ない
- 【補】PHP7.2新機能: パラメータの反変性・戻り値の共変性
- ので、AbstractPlayerMapperには
find(key)
メソッドがない
- 静的型付け言語の多くでは、オーバライドした関数の戻り値の型を変ることはできない
- Mapperを2系統に分割する
- PlayerMapper
- 抽象的にPlayerを取得する用
insert()
,update()
,delete()
の共通のロジックを定義
- AbstractPlayerMapper
- 各具象Mapperクラスの基底
- 各具象Mapperクラス
- 各具象DomainModelクラスとDBとのMappingの仕方を知っている
save()
,load()
フックメソッドをオーバライド- 【補】Template Method Pattern
- PlayerMapper
When to Use It
- 使わない場合?
- コピペ
- 凶悪犯罪
- PlayerのインタフェースをAbstractPlayerMapperに混ぜ込む
- できなくないけど複雑
- コピペ
コード例
- 採用するTable Inheritance系パターンにより様々
- 各パターンのコード例を見よ
英語
- heinous crime
- 凶悪犯罪