どうも、今月ブログ更新をサボり気味で後悔してます。
「ブログ続けてるのすごい」って言われて嬉しかったので、
更新ちゃんと頑張ります。
遡ってみると2017年1月からブログを始めて早2年経ってました。
累計113記事でした。
\目標、1000記事/
今回は、TemplateMethodについてです。
TemplateMethodとは?
メソッドにおけるアルゴリズムの骨組みを定義し、
いくつかの手順をサブクラスに先送りします。
→ アルゴリズムとなる一連の手順(メソッド)を
定義するメソッド(テンプレート)があり、
その一連の手順の中のメソッドの1つ以上を
抽象メソッドとして定義し、
サブクラスがそれを実装する
クラス図

コード
abstract class AbstractClass
{
public function templateMethod(): void
{
$this->primitiveOperation1();
$this->primitiveOperation2();
}
//それぞれ異なる手順→サブクラスにまかせる
abstract public function primitiveOperation1();
public function primitiveOperation2(): void
{
//共通の手順
}
}
class ConcreteClass extends AbstractClass
{
public function primitiveOperation1(): void
{
// TODO: Implement primitiveOperation1() method.
}
}
いざ、実装!
Head Firstデザインパターンの具体例では、
コーヒーと紅茶の作り方がでてきました。
レシピ
▶︎コーヒーの作り方 1.お湯を沸かす 2.フィルターをセットして淹れる 3.コップにコーヒーを注ぐ 4.ミルクや砂糖を加える ▶︎紅茶の作り方 1.お湯を沸かす 2.ティパックをセットしてお湯をいれる 3.レモンをいれる 4.コップに注ぐ
ざっくりみると、コーヒーと紅茶の作り方は似ているので、
1~4の一連の手順をテンプレートメソッドとしてスーパークラスに定義し、
「1.お湯を沸かす」の部分は共通化できるので、スーパークラスで実装します。
コーヒーと紅茶で異なる部分はサブクラスで実装します。
実際のコードはこちら↓
[kin29/HeadFirstDezaPata]
クラス図

コード
abstract class CaffeineBeverage
{
public function prepareRecipe(): void
{
$this->boilWater();
$this->brew();
$this->pourInCup();
$this->addCondiments();
}
abstract public function brew(): void;
abstract public function addCondiments(): void;
public function boilWater(): void
{
echo "お湯を沸かします\n";
}
public function pourInCup(): void
{
echo "カップに注ぎます\n";
}
}
class Coffee extends CaffeineBeverage
{
public function __toString(): string
{
return "--- コーヒーのレシピ ---\n";
}
public function brew(): void
{
echo "フィルターでコーヒをドリップします\n";
}
public function addCondiments(): void
{
echo "砂糖とミルクを追加します\n";
}
}
class Tea extends CaffeineBeverage
{
public function __toString(): string
{
return "--- 紅茶のレシピ ---\n";
}
public function brew(): void
{
echo "紅茶を浸します\n";
}
public function addCondiments(): void
{
echo "レモンを追加します\n";
}
}
$ php src/TemplateMethod/main.php --- コーヒーのレシピ --- お湯を沸かします フィルターでコーヒをドリップします カップに注ぎます 砂糖とミルクを追加します --- 紅茶のレシピ --- お湯を沸かします 紅茶を浸します カップに注ぎます レモンを追加します
メリット
・共通メソッドの変更が必要となった場合、
スーパクラスの変更のみでいい。
・スーパクラスで骨組みを定義しているので、
新しいカフェインクラスの追加が必要になった場合(例えばココアとか?)、
実装がしやすい
令和もがんばろーっっと











