Template Method задає каркас алгоритму в базовому класі, а окремі кроки делегує нащадкам.
Яку проблему вирішує
Кілька варіантів алгоритму мають однакову загальну структуру, але відрізняються деталями окремих кроків. Якщо копіювати весь алгоритм у кожен варіант, спільна частина дублюється, і виправлення доводиться вносити в усі копії.
Як вирішує
Базовий клас реалізує загальний алгоритм як послідовність викликів, частина яких - абстрактні чи перевизначувані методи. Нащадки заповнюють лише змінні кроки, не торкаючись каркаса.
abstract class ReportGenerator
{
public function generate(): array
{
$data = $this->fetchData();
$data = $this->transform($data);
return $this->format($data);
}
abstract protected function fetchData(): array;
protected function transform(array $data): array
{
return $data;
}
abstract protected function format(array $data): array;
}
class SalesReport extends ReportGenerator
{
protected function fetchData(): array
{
return Order::query()->pluck('total')->all();
}
protected function format(array $data): array
{
return ['sum' => array_sum($data)];
}
}
Де застосовувати
- Звіти, імпорт/експорт, пайплайни обробки зі стабільною структурою й змінними кроками.
- Коли спільний каркас треба зафіксувати, а варіювати лише деталі.
Плюси та мінуси
- + Спільна частина алгоритму не дублюється.
- + Нащадку лишається реалізувати лише змінні кроки.
- − Жорсткий каркас обмежує: якщо кроки сильно відрізняються, він заважатиме.
- − Різниця зі Strategy: Template Method варіює кроки через спадкування, Strategy - через композицію (гнучкіша). Коли реалізації розходяться сильно - краще Strategy або окремі сервіси.