Паттерн Шаблонный метод
Часть раздела Объектно-ориентированное программирование путешествия по 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
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн ObserverПаттерн Strategy5Полиморфизм
Снова о переопределении методовУтиная типизацияАбстрактные классы и методыПроектирование интерфейсовИтоги — Калькулятор фигур8Продвинутые концепции ООП
Композиция против наследованияМиксиныСтатические методы и методы классаДекораторы классовМенеджеры контекста11Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн Компоновщик3Свойства классов
Переменные экземпляра и классаДекораторы свойствПриватные атрибутыИтоги — Менеджер банковского счета6Инкапсуляция
Public, Protected, Private члены классаМодификаторы доступаСокрытие данныхДекораторы property: продвинутый уровеньИтоги: Система учета студентов12Проект: Управление библиотекой
Обзор проектаКлассы Book и UserСистема выдачи книгФункционал поискаИнтерфейс администратораТестирование и интеграцияПотренируйтесь самостоятельно: Онлайн-компилятор Python