Паттерн «Шаблонный метод» в Python: как структурировать алгоритмы
Паттерн «Шаблонный метод» в Python: как структурировать алгоритмы
Шаблонный метод (Template Method) — это поведенческий паттерн проектирования, который определяет основу алгоритма, позволяя подклассам переопределять отдельные шаги без изменения общей структуры. Он идеально подходит для ситуаций, когда несколько алгоритмов имеют общую логику, но различаются в деталях.
Проблема
Представьте, что вы разрабатываете систему для приготовления напитков. Процесс для чая и кофе включает похожие шаги: кипячение воды, заваривание, разлив в чашку, добавление ингредиентов. Однако детали некоторых этапов отличаются. Без использования паттерна пришлось бы дублировать код в каждом классе, что нарушает принцип DRY (Don’t Repeat Yourself).
Решение: Шаблонный метод
Паттерн предлагает выделить общий алгоритм в базовый класс, а изменяемые шаги сделать абстрактными. Подклассы реализуют эти шаги, сохраняя структуру алгоритма неизменной.
Пример реализации на Python
from abc import ABC, abstractmethod
class Beverage(ABC):
def prepare(self):
"""Шаблонный метод, определяющий структуру алгоритма."""
self.boil_water()
self.brew()
self.pour_in_cup()
self.add_condiments()
def boil_water(self):
print("Кипятим воду.")
def pour_in_cup(self):
print("Наливаем в чашку.")
@abstractmethod
def brew(self):
pass
@abstractmethod
def add_condiments(self):
pass
class Tea(Beverage):
def brew(self):
print("Завариваем чайные листья.")
def add_condiments(self):
print("Добавляем лимон.")
class Coffee(Beverage):
def brew(self):
print("Завариваем кофе.")
def add_condiments(self):
print("Добавляем сахар и молоко.")
# Использование
tea = Tea()
print("Готовим чай:")
tea.prepare()
coffee = Coffee()
print("\nГотовим кофе:")
coffee.prepare()
Вывод:
Готовим чай:
Кипятим воду.
Завариваем чайные листья.
Наливаем в чашку.
Добавляем лимон.
Готовим кофе:
Кипятим воду.
Завариваем кофе.
Наливаем в чашку.
Добавляем сахар и молоко.
Преимущества
- Устранение дублирования кода: Общая логика сосредоточена в базовом классе.
- Гибкость: Подклассы могут менять отдельные шаги, не затрагивая алгоритм.
- Контроль над расширением: Базовый класс может запрещать изменение шаблонного метода (например, через закрытые методы).
Недостатки
- Сложность иерархии: Множество подклассов усложняют структуру.
- Ограничения наследования: В языках без множественного наследования (как Python) возможны трудности.
Когда использовать?
- Когда алгоритм имеет неизменную последовательность шагов, но некоторые этапы вариативны.
- Когда нужно предоставить расширяемость только для отдельных частей алгоритма.
Сравнение с другими паттернами
- Стратегия: Изменяет весь алгоритм через делегирование, а Шаблонный метод — только части через наследование.
- Фабричный метод: Часто используется внутри Шаблонного метода для создания объектов.
Заключение
Шаблонный метод помогает структурировать алгоритмы, повышая переиспользуемость кода. В Python он легко реализуется через модуль abc, что делает его мощным инструментом в арсенале разработчика. Используйте его, когда хотите сохранить контроль над структурой алгоритма, но оставить пространство для кастомизации.