Menu
Coddy logo textTech

Паттерн Шаблонный метод

Часть раздела Объектно-ориентированное программирование путешествия по 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!

Ключевой момент: паттерн «Шаблонный метод» определяет общую структуру алгоритма в родительском классе, позволяя подклассам настраивать отдельные шаги. Родительский класс управляет общим потоком выполнения, а подклассы предоставляют конкретные реализации. Это обеспечивает единообразную структуру, сохраняя гибкость отдельных шагов.

challenge icon

Задание

Средне

Реализуйте паттерн «Шаблонный метод» в 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()
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Python