1. 程式人生 > 實用技巧 >PHP設計模式之模板方法模式(Template Method)程式碼例項大全(31)

PHP設計模式之模板方法模式(Template Method)程式碼例項大全(31)

目的

模板方法模式是一種讓抽象模板的子類「完成」一系列演算法的行為策略。

眾所周知的「好萊塢原則」:「不要打電話給我們,我們會打電話給你」。這個類不是由子類呼叫的,而是以相反的方式。怎麼做?當然很抽象啦!

換而言之,它是一種非常適合框架庫的演算法骨架。使用者只需要實現子類的一種方法,其父類便可去搞定這項工作了。

這是一種分離具體類的簡單辦法,且可以減少複製貼上,這也是它常見的原因。

UML圖

★官方PHP高階學習交流社群「點選」管理整理了一些資料,BAT等一線大廠進階知識體系備好(相關學習資料以及筆面試題)以及不限於:分散式架構、高可擴充套件、高效能、高併發、伺服器效能調優、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql優化、shell指令碼、Docker、微服務、Nginx等多個知識點高階進階乾貨

程式碼

  • Journey.php

<?php

namespace DesignPatterns\Behavioral\TemplateMethod;

abstract class Journey
{
    /**
     * @var string[]
     */
    private $thingsToDo = [];

    /**
     * 這是當前類及其子類提供的公共服務
     * 注意,它「凍結」了全域性的演算法行為
     * 如果你想重寫這個契約,只需要實現一個包含 takeATrip() 方法的介面
     */
    final public function takeATrip()
    {
        $this->thingsToDo[] = $this->buyAFlight();
        $this->thingsToDo[] = $this->takePlane();
        $this->thingsToDo[] = $this->enjoyVacation();
        $buyGift = $this->buyGift();

        if ($buyGift !== null) {
            $this->thingsToDo[] = $buyGift;
        }

        $this->thingsToDo[] = $this->takePlane();
    }

    /**
     * 這個方法必須要實現,它是這個模式的關鍵點
     */
    abstract protected function enjoyVacation(): string;

    /**
     * 這個方法是可選的,也可能作為演算法的一部分
     * 如果需要的話你可以重寫它
     *
     * @return null|string
     */
    protected function buyGift()
    {
        return null;
    }

    private function buyAFlight(): string
    {
        return 'Buy a flight ticket';
    }

    private function takePlane(): string
    {
        return 'Taking the plane';
    }

    /**
     * @return string[]
     */
    public function getThingsToDo(): array
    {
        return $this->thingsToDo;
    }
}
  • BeachJourney.php

<?php

namespace DesignPatterns\Behavioral\TemplateMethod;

class BeachJourney extends Journey
{
    protected function enjoyVacation(): string
    {
        return "Swimming and sun-bathing";
    }
}
  • CityJourney.php

<?php

namespace DesignPatterns\Behavioral\TemplateMethod;

class CityJourney extends Journey
{
    protected function enjoyVacation(): string
    {
        return "Eat, drink, take photos and sleep";
    }

    protected function buyGift(): string
    {
        return "Buy a gift";
    }
}

測試

  • Tests/JourneyTest.php

<?php

namespace DesignPatterns\Behavioral\TemplateMethod\Tests;

use DesignPatterns\Behavioral\TemplateMethod;
use PHPUnit\Framework\TestCase;

class JourneyTest extends TestCase
{
    public function testCanGetOnVacationOnTheBeach()
    {
        $beachJourney = new TemplateMethod\BeachJourney();
        $beachJourney->takeATrip();

        $this->assertEquals(
            ['Buy a flight ticket', 'Taking the plane', 'Swimming and sun-bathing', 'Taking the plane'],
            $beachJourney->getThingsToDo()
        );
    }

    public function testCanGetOnAJourneyToACity()
    {
        $cityJourney = new TemplateMethod\CityJourney();
        $cityJourney->takeATrip();

        $this->assertEquals(
            [
                'Buy a flight ticket',
                'Taking the plane',
                'Eat, drink, take photos and sleep',
                'Buy a gift',
                'Taking the plane'
            ],
            $cityJourney->getThingsToDo()
        );
    }
}

PHP 網際網路架構師成長之路*「設計模式」終極指南

PHP 網際網路架構師 50K 成長指南+行業問題解決總綱(持續更新)

面試10家公司,收穫9個offer,2020年PHP 面試問題

★如果喜歡我的文章,想與更多資深開發者一起交流學習的話,獲取更多大廠面試相關技術諮詢和指導,歡迎加入我們的群啊,暗號:phpzh(君羊號碼856460874)。

2020年最新PHP進階教程,全系列!

內容不錯的話希望大家支援鼓勵下點個贊/喜歡,歡迎一起來交流;另外如果有什麼問題 建議 想看的內容可以在評論提出