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