🧱

PHPでデザインパターン「Template Method」

2023/08/20に公開

目次

  1. 概要
  2. 実装
  3. 資料

概要

Template Methodパターンは親クラスで処理の大きな枠組み(テンプレート)を定義し、具体的な処理内容を子クラスで決定するパターンです。
呼び出し元のクラスからは子クラスの追加や変更が見えないため、処理の変更が容易になります。

実装

<?php

// 親クラス
abstract class AbstractDisplay
{
    public function display(): string
    {
        $html = "";
        $html .= $this->displayHeader();
        $html .= "<body>";
        $html .= $this->displayBody();
        $html .= "</body>";
        return $html;
    }

    private function displayHeader(): string
    {
        return "<head><title>Template Method</title></head>";
    }

    // 子クラスで具体的な処理を記述
    protected abstract function displayBody(): string;
}
<?php

// 子クラス1
class ListDisplay extends AbstractDisplay
{
    public function __construct(
        private array $data,
    ) {}

    protected function displayBody(): string
    {
        $body = "";
        foreach ($this->data as $key => $value) {
            $body .= "<dt>" . $key . "</dt>";
            $body .= "<dd>" . $value . "</dd>";
        }
        return $body;
    }
}

// 子クラス2
class TableDisplay extends AbstractDisplay
{
    public function __construct(
        private array $data,
    ) {}

    protected function displayBody(): string
    {
        $body = "";
        foreach ($this->data as $key => $value) {
            $body .= "<tr>";
            $body .= "<th>" . $key . "</th>";
            $body .= "<td>" . $value . "</td>";
            $body .= "</tr>";
        }
        return $body;
    }
}
<?php

use PHPUnit\Framework\TestCase;

// テストコード
class DisplayTest extends TestCase
{
    public function test_list_display(): void
    {
        $data = [
            "日本" => "東京",
            "アメリカ" => "ワシントン",
            "中国" => "北京",
        ];
        $expected = "<html><head><title>Template Method</title></head><body><dt>日本</dt><dd>東京</dd><dt>アメリカ</dt><dd>ワシントン</dd><dt>中国</dt><dd>北京</dd></body></html>";

        $ld = new ListDisplay($data);
        $result = $ld->display();
        $this->assertSame($expected, $result);
    }

    public function test_table_display(): void
    {
        $data = [
            "日本" => "東京",
            "アメリカ" => "ワシントン",
            "中国" => "北京",
        ];
        $expected = "<html><head><title>Template Method</title></head><body><tr><th>日本</th><td>東京</td></tr><tr><th>アメリカ</th><td>ワシントン</td></tr><tr><th>中国</th><td>北京</td></tr></body></html>";

        $ld = new TableDisplay($data);
        $result = $ld->display();
        $this->assertSame($expected, $result);
    }
}

資料

参考文献『PHPによるデザインパターン入門』https://shimooka.hateblo.jp/entry/20100301/1267436385
https://github.com/naoyuki42/php-design-pattern

Discussion