模板方法模式是一种让抽象模板的子类「完成」一系列算法的行为策略。php
众所周知的「好莱坞原则」:「不要打电话给咱们,咱们会打电话给你」。这个类不是由子类调用的,而是以相反的方式。怎么作?固然很抽象啦!laravel
换而言之,它是一种很是适合框架库的算法骨架。用户只须要实现子类的一种方法,其父类即可去搞定这项工做了。面试
这是一种分离具体类的简单办法,且能够减小复制粘贴,这也是它常见的缘由。算法
<?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; } }
<?php namespace DesignPatterns\Behavioral\TemplateMethod; class BeachJourney extends Journey { protected function enjoyVacation(): string { return "Swimming and sun-bathing"; } }
<?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"; } }
<?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 互联网架构师成长之路*「设计模式」终极指南shell
PHP 互联网架构师 50K 成长指南+行业问题解决总纲(持续更新)设计模式
面试10家公司,收获9个offer,2020年PHP 面试问题服务器
★若是喜欢个人文章,想与更多资深开发者一块儿交流学习的话,获取更多大厂面试相关技术咨询和指导,欢迎加入咱们的群啊,暗号:phpzh(君羊号码856460874)。架构
内容不错的话但愿你们支持鼓励下点个赞/喜欢,欢迎一块儿来交流;另外若是有什么问题 建议 想看的内容能够在评论提出