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

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

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

またまた久しぶりのPHP記事です。

Decorator、かぶせて機能アップ

構造 + オブジェクト

このパターンはオブジェクトの構造に注目したパターンで、抽象を上手く利用して機能追加を簡単に行う事を可能にするパターンです。
簡単なサンプルとして文字のサニタイズを実装してみました。

上位に位置するコンポーネント作成

機能追加を実装クラスへ移譲させるためのインターフェイスを定義します。

/*
テキスト処理用のインターフェイス
*/
interface Text
{
	public function getText();
	public function setText($text);
}

実装クラスの作成 1

確認用にサニタイズ前の文字列を表示させます。

/*
編集前のテキストを表示するクラス
*/
class PlainText implements Text
{
	//インスタンスが保持する文字列
	private $textString;
	
	//文字列を取得
	public function getText()
	{
		print $this->textString."\n";
		return $this->textString;
	}
	
	//文字列を設定
	public function setText($textString)
	{
		$this->textString = $textString;
	}
}

実装クラスの作成 2

機能を拡張させるための抽象クラスにコンポーネントを実装させます。

/*
テキスト装飾の抽象クラス
*/
abstract class TextDecorator implements Text
{
	//Text型の変数
	private $text;
	
	//コンストラクタ Text型の変数を生成
	public function __construct(Text $target)
	{
		$this->text = $target;
	}
	
	//Textが保持する文字列を取得する
	public function getText()
	{
		return $this->text->getText();
	}
	
	//Textへ文字列を設定する
	public function setText($textString)
	{
		$this->text->setText($textString);
	}
}

実装クラスの作成 3

いよいよ機能の実装を行います。
実装する機能は下記の2つです。

  • 半角小文字を半角大文字に変換する
  • 2バイト文字に変換する
/*
テキスト装飾を実装するクラス1
*/
class UpperCaseText extends TextDecorator
{
	//コンストラクタ
	public function __construct(Text $target)
	{
		parent::__construct($target);
	}
	
	/*
	半角小文字を半角大文字へ変換する
	*/
	public function getText()
	{
		$textString = parent::getText();
		return strtoupper($textString);
	}
}

/*
テキスト装飾を実装するクラス2
*/
class DoubleByteText extends TextDecorator
{
	//コンストラクタ
	public function __construct(Text $target)
	{
		parent::__construct($target);
	}
	
	/*
	テキストを全角文字に変換する
	*/
	public function getText()
	{
		$textString = parent::getText();
		return mb_convert_kana($textString,"RANSKV","UTF-8");
	}
}

使ってみる

サニタイズを試してみましょう。

$textString = "abCdefG";

//装飾前の表示
$plainText = new PlainText();
$plainText->setText($textString);

//小文字を大文字に変換する
$upperCaseText = new UpperCaseText($plainText);
print $upperCaseText->getText()."\n\n";

//半角を全角へ変換する
$doubleByteText = new DoubleByteText($plainText);
print $doubleByteText->getText()."\n";
$php decorator.php
abCdefG
ABCDEFG

abCdefG
abCdefG

実装の責任を子クラスに移譲して、簡単に実現することが可能になりました。
構造が少し複雑になりがちなので気をつけて使いたいパターンですね!

Add a Comment

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