[写経] PHPで学ぶデザインパターン03
|— 注意 —
PHPによるデザインパターンの写経ですが、まんま書くと問題があるのでアウトプットとして備忘録メモです
初心者には分かりやすくて良い本なので、是非本屋でチェックして下さい。
URL : http://www.amazon.co.jp/PHPによるデザインパターン入門-下岡-秀幸/dp/4798015164
PHPによるデザインパターン入門
AdapterでAPIを変更する(継承編)
構造 + クラス、オブジェクト
既にテスト済みのクラスに対して新しいAPIを提供したり、既存API + アルファの機能を追加するときに使えるデザインパターンです。
主な目的は「既存クラスに手を加えずに再利用する」事です。
また、Adapterパターンは継承を利用するパターンと移譲を利用するパターンがあります。
まず継承パターンを見て行きましょう。
今まで使われていて既にテスト済みのクラス
ロジックは論点がずれるので簡易的にしています。
生まれ年から年齢を計算するだけ。
/* 今まで使われていて既にテスト済みのクラス */ class AlreadyTested{ //生まれ年から年齢を計算して自分の情報を表示する public function printCalculateAge($born) { print ( (int)date("Y") - (int)$born ); } }
新しく提供するAPI(インターフェース)
利用する側が分かりやすい名前にしてみる。
/* クライアントが利用するインターフェース */ interface Target{ //自分の情報を表示する public function printYourAge($born); }
クライアントが利用するAPIを提供する新しいクラス
年齢の計算だけではなく、プレフィックスとサフィックスを提供してみる。
/* クライアントが利用するAPIを提供する新しいクラス */ class NewApiDefined extends AlreadyTested implements Target{ //元のAPIを隠ぺいする public function printCalculateAge($born) { throw new RuntimeException ("未公開なんだよ!!"); } //新しいAPIを公開する public function printYourAge($born) { print "私の年齢は"; parent::printCalculateAge($born); print "歳です。"; } }
使ってみる
新しく提供されたAPIを使ってみよう。
//新しいAPIを呼び出してみる $newApi = new NewApiDefined(); $newApi->printYourAge(1977); //元のAPIを呼び出してみる $newApi->printCalculateAge(1977);
$php adapter.php 私の年齢は37歳です。 Fatal error: Uncaught exception 'RuntimeException' with message '未公開なんだよ!!' in ..
AdapterでAPIを変更する(移譲編)
クライアントが利用APIを提供する新しいクラス
テスト済のオブジェクトを利用するように変更します。
/* クライアントが利用するAPIを提供する新しいクラス (移譲) */ class NewApiDefinedUseObject implements Target{ //既にテスト済のオブジェクト private $alreadyTested; //移譲先のオブジェクトを生成する public function __construct() { $this->alreadyTested = new AlreadyTested(); } //新しいAPIを公開する public function printYourAge($born) { print "私の年齢は"; $this->alreadyTested->printCalculateAge($born); print "歳です。"; } }
使ってみる
新しく提供されたAPIを使ってみよう。
ついでに未実装のprintCalculateAgeにアクセス出来ないことも確認しておきます。
//新しいAPIを呼び出してみる $newApi = new NewApiDefinedUseObject(); $newApi->printYourAge(1977); //元のAPIを呼び出してみる $newApi->printCalculateAge(1977);
$php adapter.php 私の年齢は37歳です。 Fatal error: Call to undefined method NewApiDefinedUseObject::printCalculateAge() in ..
オブジェクト指向っぽくなってきましたね!
依存関係を整理できるDIコンテナを取り入れるなら移譲を使ったアダプターパターンが相性が良さそうな気がします。