Template Methodパターンとは
スーパークラスで処理の枠組みを定め、サブクラスでその具体的内容を定めるようなデザインパターンのことをテンプレートメソッドパターンと呼びます。
Template Methodパターンで登場する概念
AbstractClass(抽象クラス)
抽象メソッドを宣言する。
処理を実装するのは次のConcreateClassになる。
実際の処理内容は記載しないが、ある程度処理の流れを形作ることが重要。
ConcreateClass(具象クラス)
抽象メソッドを具体的に実装する。
1つのAbstractClass(抽象クラス)に対して複数のConcreateClass(具象クラス)を作成することで、同じ型(テンプレート)のクラスを作成することができる。
またサブクラスとして、スーパークラスで宣言されている抽象メソッドを実装する責任が生じており、これをsubclass responsibility(サブクラスの責任)と呼ぶ。
簡単なコードを書いてみる
AbstractClass(抽象クラス)
abstract class AbstractDisplay
{
abstract protected function open();
abstract protected function output();
abstract protected function close();
public function display()
{
$this->open();
for ($i = 0; $i < 5; $i++) {
$this->output();
}
$this->close();
}
}
実際にopen,output,closeで行う処理はまだ定義されていないが、次に具象クラスで定義する。
共通メソッドであるdisplayを呼び出すことで、それぞれの具象クラスで定義をするopen→output(5回)→closeが呼ばれる処理の流れを作成した。
ConcreateClass(具象クラス)
class CharDisplay extends AbstractDisplay
{
private $string;
public function __construct($string)
{
$this->string = $string;
}
protected function open()
{
echo "<<";
}
protected function output()
{
echo $this->string;
}
protected function close()
{
echo ">>" . PHP_EOL;
}
}
AbstractDisplayクラスを継承して、最低限実装が必要なメソッドのみ実装する。
ConcreateClass(具象クラスその2)
class StringDisplay extends AbstractDisplay
{
private $string;
private $width;
public function __construct($string)
{
$this->string = $string;
$this->width = mb_strlen($string);
}
protected function open()
{
$this->outputLine();
}
protected function output()
{
echo "|" . $this->string . "|" . PHP_EOL;
}
protected function close()
{
$this->outputLine();
}
private function outputLine()
{
echo "+";
for ($i = 0; $i < $this->width; $i++) {
echo "-";
}
echo "+" . PHP_EOL;
}
}
こちらも同じくAbstractDisplayクラスを継承して各メソッドを実装する。
それぞれのメソッド内容はCharDisplayクラスとは違ったものにする。
呼び出しを行う
$char = new CharDisplay('a');
$char->display();
$string = new StringDisplay('Hello world');
$string->display();
/*
<<aaaaa>>
+-----------+
|Hello world|
|Hello world|
|Hello world|
|Hello world|
|Hello world|
+-----------+
*/
それぞれの具象クラスでdisplayメソッドを呼び出すとコメントのようになる。
このように同じような処理をする場合には、先に抽象クラスで枠組みを決めて、実際に具象クラスで実装をするのがテンプレートメソッドパターンである。
メリット
同じような処理をするときは同じようなメソッドが必要になるためロジックの共通化ができる。
もちろん元のクラスをコピペして新しいクラスを作ることもできるが、共通部分に不具合があった場合にすべてのクラスを修正しなければいけなかったりする。
参考
Java言語で学ぶデザインパターン入門