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

[写経] PHPで学ぶデザインパターン04

— 注意 —
PHPによるデザインパターンの写経ですが、まんま書くと問題があるのでアウトプットとして備忘録メモです

初心者には分かりやすくて良い本なので、是非本屋でチェックして下さい。

URL: http://www.amazon.co.jp/PHPによるデザインパターン入門-下岡-秀幸/dp/4798015164
PHPによるデザインパターン入門

Factory Methodで生成処理を分離する

生成 + クラス

[写経] PHPで学ぶデザインパターン01のテンプレートメソッドを実装部から分離する為のパターンです。

クライアントに提供するインターフェイス

/*
クライアントが利用するインターフェース
*/
interface Country{
	//自分の情報を表示する
	public function printYourAge($born);
}

Factoryにより生成されるクラス群

/*
Factoryにより生成される日本人クラス
*/
class Japanese implements Country{
	//自分の情報を表示する
	public function printYourAge($born){
		print '私の年齢は';
		print ( (int)date('Y') - (int)$born );
		print '歳です。\n';
	}
}
/*
Factoryにより生成されるアメリカ人クラス
*/
class American implements Country{
	//自分の情報を表示する
	public function printYourAge($born){
		print 'I'm ';
		print ( (int)date('Y') - (int)$born );
		print ' years old.\n';
	}
}

エラーパターン確認の為に不正なクラスを準備(テストコード用なので任意)

/*
Countryを実装していないペンギン村クラス
*/
class PenguinVillage{
	//自分の情報を表示する
	public function printYourAge($born){
		print 'ペンギン村では';
		print ( (int)date('Y') - (int)$born );
		print 'ペンギンです。\n';
	}
}

オブジェクトを生成するFactoryクラス

インターフェイスが未実装の場合とクラス自体が未定義の場合は例外を投げるようにしています。
個人的にはですが、PHPは動的型付け言語なのでチェックを追加する方が良い気がします。

/*
Factoryクラス
*/
class Factory{
	//オブジェクト生成メソッド (IPアドレスから国を算出するとか)
	public static function CreatObject($country){
		if(class_exists($country)){
			$obj = new $country;
			if($obj instanceof Country){
				return new $country;
			}else{
				//インターフェースを実装していない場合は例外を投げる
				throw new RuntimeException ('Countryインターフェースではありません');			}
		}else{
			//未定義の場合は例外を投げる
			throw new RuntimeException ($country.'ってどこ?');
		}
	}
}

さぁ、使ってみましょう

まずは正常系から

/*
利用してみる
*/
//日本人を生成
$japanese = Factory::CreatObject('Japanese');
$japanese->printYourAge(1977);

//アメリカ人を生成
$american = Factory::CreatObject('American');
$american->printYourAge(1977);

結果確認

$php factory.php
私の年齢は37歳です。
I'm 37 years old.

例外も確認しておきましょう。
まずは未定義のクラス生成を依頼された場合

//未定義のイタリア人を生成
$italian = Factory::CreatObject('Italian');
$italian->printYourAge(1977);

結果確認

$php factory.php
Fatal error: Uncaught exception 'RuntimeException' with message 'Italianってどこ?' in ...

定義済みだがインターフェイスを実装していないクラス生成を依頼された場合

//未実装のペンギン村を生成
$penguinVillage = Factory::CreatObject('PenguinVillage');
$penguinVillage->printYourAge(1977);

結果確認

$php factory.php
Fatal error: Uncaught exception 'RuntimeException' with message 'Countryインターフェースではありません' in ..

Add a Comment

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