ここでは、PHP による Adapter パターンの実装例を掲載しています。Adapter パターンとは、ある既存クラスのを修正することなく、インターフェースを変更する実装例になります。
スポンサーリンク
PHP による Adapter パターン実装例
ある会社の基準給や住宅手当の基準額を算出する以下のクラス(StandardSalary)を例に、 Adapter パターンを説明します。
// 給与基準 class StandardSalary { // 基準給を返す public function getBasic() { /* * 色々計算を行う(年齢や、実績などを加味) */ return $pay; } // 住宅手当を返す public function getHousing() { /* * 色々計算を行う(地域の地価などを加味) */ return $pay; } }
このクラスのメソッドと全く同じ機能を有する別名のインターフェースを追加することを考えます。既存のクラスには修正を加えないことが条件なので、1つの方法としては派生クラスを作成し、親クラスのメソッドを呼び出す方法があります。
特に上記コードの計算が、保険のように(意図的に複雑にして損得を分かりづらくさせ) カオスの様相を呈している場合などは、既存クラスの内容をコピーして別クラスを作成すると、カオスに不具合があると、コピー先のカオスも修正しなくてはならなくなるので修正漏れが発生しやすくなってしまいます。
継承を利用した Adapter パターン
// 新規クラスで実装するインターフェース interface SpecialSalaryInterface { public function getSpecial(); } // 特別給与 class SpecialSalary extends StandardSalary implements SpecialSalaryInterface { // 特別給与も名前だけ(ブラックだぜ~) public function getSpecial() { // 親クラスメソッドを呼び出す return parent::getBasic(); } // 親クラスで使わせたくないメソッドは private で修飾することもできる private function getHousing() { } }
特別給与といえど、実は基本給と同じということに意味はありませんが、既存クラスに修正を加えることなく、同一機能を異なるインターフェース(getSpecial)に持たせていることがわかります。
委譲を利用した Adapter パターン
継承を利用する方法は、既存クラスが final キーワードで継承不可能である場合は使用することができません。この時は以下のように、委譲による方法で既存クラスに修正を加えることなく既存クラスをそのまま利用させることができます。
// 新規クラスで実装するインターフェース interface SpecialSalaryInterface { public function getSpecial(); } // 特別給与 class SpecialSalary implements SpecialSalaryInterface { public function getSpecial() { $basic = new BasicSalary(); return $basic->getBasic(); } }
上記のサンプルコードでは、getSpecial インターフェースで既存クラス(BasicSalary)のインスタンス生成していますが、何度も呼び出されるような場合には、コンストラクタなどでインスタンス生成を行い、属性(メンバ変数)としてインスタンスを保持させておけばよいでしょう。
オブジェクト指向、継承と移譲の勉強をしていて、こちらのサイトにたどり着きました。
わかりやすかったので目を通していたのですが、自分の今までの理解からすると、
3つ目のソースの12行目、
$basic = new BasicSalary();
は
$basic = new StandardSalary():
の間違いではないのでしょうか。
通りすがりですが質問させていただきました。