テンプレートの機能を持つパターン。
スーパークラスの方にテンプレートとなるメソッドが定義されていて、
そのメソッドの中では抽象メソッドが使われている。
その抽象メソッドを実装するのはサブクラスの役目なので、
同じメソッド名でも、違うサブクラスで違う処理を書くことも出来る。
しかし、どのような処理を書こうとも、
処理の大きな流れはスーパークラスで組み立てたとおりになる。
このようにスーパークラスで処理の枠組みを定め、
サブクラスでその内容を定めるようなパターンをTemplate Methodパターンという
文字や文字列を5回繰り返して表示する、という処理を例にとる
open、show、close、displayというメソッドを持っているクラス。
しかし、それぞれのメソッドは具体的な処理は無く、
プログラムの大枠や流れだけが定義されている。
<?php abstract class AbstractDisplay { public abstract function open(); public abstract function show(); public abstract function close(); public final function display() { $this->open(); for ($i = 0; $i < 5; $i++) { $this->show(); } $this->close(); } } ?>
サブクラスの1つ。
スーパークラスでは抽象メソッドだったものが、ここで実際に定義されている。
<?php require_once("AbstractDisplay.class.php"); class CharDisplay extends AbstractDisplay { private $char; public function __construct($display_char) { $this->char = $display_char; } public function open() { echo "<<"; } public function show() { echo " ".$this->char." "; } public function close() { echo ">>"; echo "<br />"; } } ?>
サブクラスの1つ。
ここでもスーパークラスでは抽象メソッドだったものが、実際に定義されている。
<?php require_once("AbstractDisplay.class.php"); class StringDisplay extends AbstractDisplay { private $string; private $width; public function __construct($display_string) { $this->string = $display_string; $this->width = strlen(bin2hex($display_string))/2; } public function open() { self::printLine(); } public function show() { echo "| ".$this->string." |"; echo "<br />"; } public function close() { self::printLine(); } private function printLine() { echo "+"; for ($i = 0; $i < $this->width - 2; $i++) { echo "-"; } echo "+"; echo "<br />"; } } ?>
実行クラス
<?php require_once("CharDisplay.class.php"); require_once("StringDisplay.class.php"); class Main { public function main() { $d1 = new CharDisplay("H"); $d2 = new StringDisplay("Hellow, World."); $d3 = new StringDisplay("こんにちは。"); $d1->display(); echo "<br />"; $d2->display(); echo "<br />"; $d3->display(); } } new Main(); ?>
テンプレートメソッドを実装するクラス。
また、そのテンプレートメソッドで使っている抽象メソッドを宣言する。
AbstractClass?で定義された抽象メソッドを具体的に実装する。
スーパークラスでアルゴリズムが記述されているので、
サブクラス側でアルゴリズムを記述する必要が無くなる。
Template Methodパターンをインスタンス生成に応用した例が
Factory Methodパターン
Template Methodパターンでは「継承」を利用してプログラムの動作を変更することができる。
スーパークラスでプログラムの大枠を定め、サブクラスで具体的な振る舞いを定めるからです。
これに対し、「委譲」を利用してプログラムの動作を変更することができるのが
Strategyパターンです。
これはプログラムの一部を変更するというよりは、アルゴリズムをごっそり切り替える場合に使用する。
参考資料