Паттерн «Шаблонный метод»
Часть раздела Объектно-ориентированное программирование путешествия по Python на Coddy. Урок 52 из 64.
Шаблонный метод определяет каркас алгоритма в базовом классе, позволяя подклассам переопределять отдельные шаги, не изменяя структуру алгоритма.
Вот базовый класс с шаблонным методом:
class DataProcessor:
def process(self):
"""Шаблонный метод, определяющий структуру алгоритма"""
self.read_data()
self.process_data()
self.save_data()
def read_data(self):
print("Reading data...")
def process_data(self):
raise NotImplementedError("Subclasses must implement this")
def save_data(self):
print("Saving data...")Шаблонный метод process() определяет шаги алгоритма, а реализацию process_data() оставляют подклассам.
Создайте конкретные классы, реализующие абстрактный метод:
class CSVProcessor(DataProcessor):
def process_data(self):
print("Processing CSV data")
class JSONProcessor(DataProcessor):
def process_data(self):
print("Processing JSON data")Каждый конкретный класс предоставляет собственную реализацию необходимого шага.
Используй шаблонный метод:
csv_processor = CSVProcessor()
csv_processor.process()
print() # Пустая строка
json_processor = JSONProcessor()
json_processor.process()Создай ещё один пример с шаблоном игры:
class Game:
def play(self):
"""Шаблонный метод для игры"""
self.start_game()
self.play_game()
self.end_game()
def start_game(self):
print("Game started!")
def play_game(self):
raise NotImplementedError("Define the game rules")
def end_game(self):
print("Game ended!")
class Chess(Game):
def play_game(self):
print("Playing chess - thinking strategically...")
class Soccer(Game):
def play_game(self):
print("Playing soccer - running and kicking...")
chess = Chess()
chess.play()Вывод:
Reading data...
Processing CSV data
Saving data...
Reading data...
Processing JSON data
Saving data...
Game started!
Playing chess - thinking strategically...
Game ended!Ключевой момент: шаблонный метод задаёт общую структуру алгоритма в родительском классе, позволяя подклассам настраивать отдельные шаги. Родительский класс управляет общим ходом выполнения, а подклассы предоставляют конкретные реализации. Это обеспечивает единообразную структуру и при этом позволяет гибко настраивать отдельные шаги.
Задание
СреднеРеализуй шаблонный метод в template.py. Абстрактный класс Report содержит шаблонный метод generate(), который всегда выполняет одни и те же три шага в одном и том же порядке: header(), body(), footer().
header()общий для всех отчётов и выводит=== Report ===.body()— абстрактный метод: каждый подкласс выводит собственное содержимое.footer()— хук с реализацией по умолчанию=== End ===, которую подкласс может переопределить.
Затем напиши два конкретных отчёта:
SalesReport(total)сохраняет итоговое значение вself._totalи выводитTotal sales: {total}в теле отчёта.InventoryReport(items)сохраняет список вself._items, выводитItem: {item}для каждого элемента в теле отчёта и переопределяет нижний колонтитул, чтобы выводить=== {count} items ===.
driver.py заблокирован: он создаёт отчёты и вызывает для них generate(). Между подклассами различаются только шаги; порядок шагов задаётся один раз в базовом классе.
Попробуйте сами
from template import SalesReport, InventoryReport
# Обработчик тестового случая (не изменять)
test_case = input()
if test_case == "sales_test":
SalesReport(1500).generate()
elif test_case == "inventory_test":
InventoryReport(["Laptop", "Mouse"]).generate()
elif test_case == "both_test":
for report in [SalesReport(200), InventoryReport(["Pen"])]:
report.generate()
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Введение в ООПВнешние файлыКлассы и объектыПараметр selfМетодыАтрибутыМетод-конструктор (__init__)Повторение — простой калькулятор4Наследование
Основы наследованияФункция super()Переопределение методовМножественное наследованиеПорядок разрешения методовПовторение: иерархия сотрудников7Специальные методы
Введение в магические методыПерегрузка операторовМагические методы контейнеровПовторение — пользовательский список10Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн «Одиночка»Паттерн «Фабрика»Паттерн «Наблюдатель»Паттерн «Стратегия»2Декораторы
Введение в декораторыДекоратор свойстваДекоратор статического методаДекоратор метода класса5Полиморфизм
Переопределение методов: повторениеУтиная типизацияАбстрактные классы и методыПроектирование интерфейсовПовторение — калькулятор фигур8Продвинутые концепции ООП
Композиция и наследованиеМиксиныСтатические методы и методы классаДекораторы классовМенеджеры контекста11Паттерны проектирования. Часть 2
Паттерн «Команда»Паттерн «Адаптер»Паттерн «Декоратор»Паттерн «Шаблонный метод»Паттерн «Состояние»Паттерн «Компоновщик»3Свойства классов
Переменные экземпляра и классаДекораторы свойствПриватные атрибутыПовторение — менеджер банковского счёта6Инкапсуляция
Публичные, защищённые и приватные членыМодификаторы доступаСокрытие информацииПродвинутые декораторы свойствПовторение — система учёта студентов12Проект: Система управления библиотекой
Обзор проектаКлассы книг и пользователейСистема выдачи книгФункция поискаИнтерфейс администратораТестирование и интеграцияПотренируйтесь самостоятельно: Онлайн-компилятор Python