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

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

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

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

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

Chain of Responsibilityで処理のたらい回し

振る舞い + オブジェクト

このパターンは、ifやswitch文などの分岐条件で行うような一連の手続きの1つづつの責務(1つのif文やswitchの1条件)を分離して、「処理を依頼する側」と「実際に処理を行う側」を分離する為のパターンです。

書籍のサンプルもそうですが、データの検証(バリデーション)パターンでの利用が分かりやすいと思います。

抽象クラスの作成

バリデーションの責務を持つ各クラス(英字だけ、数字だけ、特定文字数など)を内部に保持する抽象クラスを作成します。
*内部に保持するハンドラー(責務クラス)をハンドルする抽象クラスです。

実装はシンプルなので読めば分かると思いますが、似た単語が並ぶので分かり難いと感じる方は言葉の整理を行ってみてください。

/*
バリデーションの抽象クラス
*/
abstract class ValidationHandler
{

	//ハンドラー保持変数
	private $next_handler;

	//コンストラクタ
	public function __construct()
	{
		$this->next_handler = null;
	}

	//ハンドラーの設定
	public function setHandler(ValidationHandler $handler)
	{
		$this->next_handler = $handler;
		return $this;
	}

	//ハンドラーの取得
	public function getNextHandler()
	{
		return $this->next_handler;
	}

	//責務の実行 継承先クラスのメイン処理
	public function validate($input)
	{
		$result = $this->execValidation($input);
		if(!$result)
		{
			return $this->getErrorMessage();
		} elseif (!is_null($this->getNextHandler())) {
			return $this->getNextHandler()->validate($input);
		} else {
			return null;
		}
	}

	//実処理
	protected abstract function execValidation($input);
	//メッセージ取得
	protected abstract function getErrorMessage();
}

検証クラスの作成

半角英字、文字数の検証責務を持つ検証クラスを作成します。
抽象クラスの抽象メソッドを具体的に実装していきます。

/*
英字チェッククラス
*/
class AlphabetValidation extends ValidationHandler
{
	//実処理
	protected function execValidation($input)
	{
		return (preg_match('/^[a-z]*$/i',$input) > 0);
	}

	//メッセージ取得
	public function getErrorMessage()
	{
		return '半角英字で入力してください';
	}
}
/*
文字数チェッククラス
*/
class MaxLengthValidation extends ValidationHandler
{
	//最大文字数
	private $max_length = 10;
	//コンストラクタ
	public function __construct($max_length=10) {
		$this->max_length = (int)$max_length;
	}
	//実処理
	protected function execValidation($input)
	{
		return (strlen($input)<=$this->max_length);
	}
	//メッセージ取得
	public function getErrorMessage()
	{
		return $this->max_length.'バイト内で入力してください';
	}
}

使ってみる

5文字以内の半角英字のみOKとなるパターンでチェックを行ってみます。

$handler = new AlphabetValidation();
$handler->setHandler(new MaxLengthValidation(5));

$input = "abc";
$result = $handler->validate($input);
print ( empty($result) ? 'OK!' : $result)."\n";

$input = "abcdefghijk";
$result = $handler->validate($input);
print ( empty($result) ? 'OK!' : $result)."\n";
$php chainOfResponsibility.php
OK!
5バイト内で入力してください

Webアプリケーションではよく利用するパターンなので、色々な組み合わせで試してみてください。

Add a Comment

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