目的
テンプレートメソッドパターンは、抽象テンプレートのサブクラスが一連のアルゴリズムを「完了する」ことを可能にする動作戦略です。
よく知られている「ハリウッドの原則」:「私たちに電話しないで、私たちはあなたに電話します。」このクラスはサブクラスからは呼び出されませんが、逆の方法で呼び出されます。どうやってするの?もちろん、それは非常に抽象的なものです!
つまり、フレームワークライブラリに非常に適したアルゴリズムスケルトンです。ユーザーはサブクラスのメソッドを実装するだけでよく、親クラスがその仕事を実行できます。
これは具象クラスを分離する簡単な方法であり、コピーと貼り付けを減らすことができます。これも一般的な理由です。
UML图
コード
- 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 Internet Architectの成長パス*「デザインパターン」の究極のガイド
PHP Internet Architect 50K Growth Guide + Industry Problem Solving Guide(Continuous Update)
10社へのインタビュー、9件のオファー、2020年のPHPインタビューの質問
★私の記事が好きで、より多くの上級開発者とコミュニケーションを取り、学びたい場合は、主要企業へのインタビューに関連するより多くの技術的なコンサルティングとガイダンスを取得してください。
2020年の最新のPHP高度なチュートリアル、フルシリーズ!
内容が良かったら、いいね、いいね!を付けて、コミュニケーションを歓迎します。また、質問がある場合は、コメントで見たいものを提案してください。