Паттерн Шаблонный метод (Template Method) в PHP
Короткий скринкаст: паттерн «Шаблонный метод» (Template Method) — задаёт скелет алгоритма, делегируя детали подклассам. На примере приготовления чая и кофе.
Описание
Шаблонный метод определяет общий порядок действий в алгоритме, оставляя реализацию некоторых шагов подклассам. Базовый абстрактный класс CaffeineBeverage содержит метод prepareRecipe(), помеченный как final — это и есть шаблонный метод. Общие шаги (boilWater, pourInCup) реализованы в базовом классе, а отличающиеся (brew, addCondiments) объявлены абстрактными. Подклассы Tea и Coffee реализуют только свои вариации этих шагов.
UML-диаграмма
Код
CaffeineBeverage.php
abstract class CaffeineBeverage
{
final public function prepareRecipe(): void
{
$this->boilWater();
$this->brew();
$this->pourInCup();
$this->addCondiments();
}
protected function boilWater(): void
{
echo "Boiling water\n";
}
protected function pourInCup(): void
{
echo "Pouring into cup\n";
}
abstract protected function brew(): void;
abstract protected function addCondiments(): void;
}
Tea.php
class Tea extends CaffeineBeverage
{
protected function brew(): void
{
echo "Steeping the tea\n";
}
protected function addCondiments(): void
{
echo "Adding lemon\n";
}
}
Coffee.php
class Coffee extends CaffeineBeverage
{
protected function brew(): void
{
echo "Dripping coffee through filter\n";
}
protected function addCondiments(): void
{
echo "Adding sugar and milk\n";
}
}
demo.php
require_once 'CaffeineBeverage.php';
require_once 'Tea.php';
require_once 'Coffee.php';
$tea = new Tea;
$tea->prepareRecipe();
echo "\n";
$coffee = new Coffee;
$coffee->prepareRecipe();
Пример результата
Boiling water
Steeping the tea
Pouring into cup
Adding lemon
Boiling water
Dripping coffee through filter
Pouring into cup
Adding sugar and milk
Преимущества
- Избегается дублирование кода: общий алгоритм хранится в одном месте.
- Подклассы переопределяют только то, что действительно отличается.
- Легко расширять, не меняя структуру алгоритма.
- Контролирует последовательность шагов.
Когда использовать
- Когда у нескольких классов есть общий алгоритм, но шаги различаются.
- Когда нужно избежать дублирования кода в подклассах.
- Когда важно зафиксировать порядок выполнения шагов.
- Когда некоторые шаги обязательны для всех подклассов.
Использование в Laravel
В Laravel шаблонный метод часто встречается в абстрактных классах и трейтах. Например, в миграциях базовые классы задают порядок действий, а разработчик переопределяет детали. Также в сервис-провайдерах и в некоторых пакетах используются абстрактные классы с шаблонным методом для унификации поведения.