=====Шаблонный метод=====
**Шаблонный метод** — это поведенческий паттерн, задающий скелет алгоритма в суперклассе и заставляющий подклассы реализовать конкретные шаги этого алгоритма. \\
\\
**Применимость:** Шаблонные методы можно встретить во многих PHP-фреймворках. Разработчики создают такие методы, чтобы позволить клиентам легко и быстро расширять стандартный код при помощи наследования.\\
\\
**Признаки применения паттерна:** Класс заставляет своих потомков реализовать методы-шаги, но самостоятельно реализует структуру алгоритма.\\
\\
baseOperation1();
$this->requiredOperations1();
$this->baseOperation2();
$this->hook1();
$this->requiredOperation2();
$this->baseOperation3();
$this->hook2();
}
/**
* Эти операции уже имеют реализации.
*/
protected function baseOperation1(): void
{
echo "AbstractClass says: I am doing the bulk of the work\n";
}
protected function baseOperation2(): void
{
echo "AbstractClass says: But I let subclasses override some operations\n";
}
protected function baseOperation3(): void
{
echo "AbstractClass says: But I am doing the bulk of the work anyway\n";
}
/**
* А эти операции должны быть реализованы в подклассах.
*/
abstract protected function requiredOperations1(): void;
abstract protected function requiredOperation2(): void;
/**
* Это «хуки». Подклассы могут переопределять их, но это не обязательно,
* поскольку у хуков уже есть стандартная (но пустая) реализация. Хуки
* предоставляют дополнительные точки расширения в некоторых критических
* местах алгоритма.
*/
protected function hook1(): void { }
protected function hook2(): void { }
}
/**
* Конкретные классы должны реализовать все абстрактные операции базового
* класса. Они также могут переопределить некоторые операции с реализацией по
* умолчанию.
*/
class ConcreteClass1 extends AbstractClass
{
protected function requiredOperations1(): void
{
echo "ConcreteClass1 says: Implemented Operation1\n";
}
protected function requiredOperation2(): void
{
echo "ConcreteClass1 says: Implemented Operation2\n";
}
}
/**
* Обычно конкретные классы переопределяют только часть операций базового
* класса.
*/
class ConcreteClass2 extends AbstractClass
{
protected function requiredOperations1(): void
{
echo "ConcreteClass2 says: Implemented Operation1\n";
}
protected function requiredOperation2(): void
{
echo "ConcreteClass2 says: Implemented Operation2\n";
}
protected function hook1(): void
{
echo "ConcreteClass2 says: Overridden Hook1\n";
}
}
/**
* Клиентский код вызывает шаблонный метод для выполнения алгоритма. Клиентский
* код не должен знать конкретный класс объекта, с которым работает, при
* условии, что он работает с объектами через интерфейс их базового класса.
*/
function clientCode(AbstractClass $class)
{
// ...
$class->templateMethod();
// ...
}
echo "Same client code can work with different subclasses:\n";
clientCode(new ConcreteClass1());
echo "\n";
echo "Same client code can work with different subclasses:\n";
clientCode(new ConcreteClass2());
====Результат выполнения====
Same client code can work with different subclasses:
AbstractClass says: I am doing bulk of the work
ConcreteClass1 says: Implemented Operation1
AbstractClass says: But I let subclasses to override some operations
ConcreteClass1 says: Implemented Operation2
AbstractClass says: But I am doing bulk of the work anyway
Same client code can work with different subclasses:
AbstractClass says: I am doing bulk of the work
ConcreteClass2 says: Implemented Operation1
AbstractClass says: But I let subclasses to override some operations
ConcreteClass2 says: Overridden Hook1
ConcreteClass2 says: Implemented Operation2
AbstractClass says: But I am doing bulk of the work anyway