cheka.jp 超不定期で更新する写真達。お口直しにどうぞ。

[写経] 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コンテナを取り入れるなら移譲を使ったアダプターパターンが相性が良さそうな気がします。

Add a Comment

メールアドレスが公開されることはありません。