Template Methodパターン

設計

使いどころ

  • 複数のクラスで共通の処理を行いたい
  • 決まった手順で処理を実行したい

TemplateMethodパターンは、抽象クラスに共通の処理であるテンプレートメソッド(AbstractAnimalクラスのcryVoice())を定義することにより、実現されます。

ソースコードを見てわかる通り、定義されているメソッドが同じかつ、そのメソッド達の実行手順が決まっているサブクラスを複数作成したい時に便利です。抽象クラスにテンプレートメソッドしてまとめるので、各サブクラスで同様の処理が重複するなどのリスクが低下します。また実行したい処理がまとまっているので、可読性が増します。

ただ単に処理を抽象クラスで共通化するだけではなく、「処理の共通化かつ、共通化した処理の実行順も共通化させる」ということが重要です。

しかしテンプレートメソッドで使用する抽象メソッドが増えれば増えるほど、複雑になり、冗長になるので注意が必要そうです。

ソースコード

AbstractClass(抽象クラス)

AbstractAnimal.php

抽象クラスには、テンプレートメソッド(cryメソッド)と抽象メソッドがあります。抽象メソッドの具体な処理は、具象クラスの方でオーバーライドします。実際に実行ファイルから呼ばれる処理はこのテンプレートメソッドになります。

<?php

abstract class AbstractAnimal {
    abstract public function start();

    abstract public function cryVoice();

    abstract public function end();

    // finalキーワードはオーバーライドさせない為に使用
    // 5回泣いてもらう
    final public function cry() {
        $this->start();
        for ($i = 0; $i < 5; $i++) {
            $this->cryVoice();
        }
        $this->end();
    }
}

ConcreteClass(具象クラス)

Dog.php

抽象クラスを継承して使います。抽象クラスで実装されている抽象メソッドをオーバーライドして、具体的な処理を実装します。

以下では、コンストラクタで受け取った引数(動物の鳴き声)を画面上に出力する予定です。

<?php
require_once __DIR__."/AbstractAnimal.php";

class Dog extends AbstractAnimal {
    private $voice;

    function __construct($voice) {
        $this->voice = $voice;
    }

    public function start() {
        echo "犬:";
    }

    public function end() {
        echo "<br>";
    }

    public function cryVoice() {
        echo $this->voice;
    }
}

Cat.php

<?php
require_once __DIR__."/AbstractAnimal.php";

class Cat extends AbstractAnimal {
    private $voice;

    function __construct($voice) {
        $this->voice = $voice;
    }

    public function start() {
        echo "猫:";
    }

    public function end() {
        echo "<br>";
    }

    public function cryVoice() {
        echo $this->voice;
    }
}

出力結果

参考:

コメント

タイトルとURLをコピーしました