Ответ
Паттерн 'Стратегия' — это поведенческий паттерн проектирования, который позволяет определять семейство алгоритмов, инкапсулировать каждый из них и делать их взаимозаменяемыми. Это позволяет клиенту выбирать нужный алгоритм во время выполнения.
Компоненты паттерна:
- Context (Контекст): Класс, который использует одну из стратегий. Он хранит ссылку на объект-стратегию и делегирует ему выполнение алгоритма.
- Strategy (Стратегия): Абстрактный базовый класс или интерфейс, который определяет общий метод для всех конкретных стратегий.
- ConcreteStrategy (Конкретная стратегия): Классы, реализующие интерфейс
Strategy, каждый со своей версией алгоритма.
Пример реализации
Представим, что у нас есть контекст, который должен сортировать данные, но способ сортировки может меняться.
from abc import ABC, abstractmethod
from typing import List, Type
# 1. Интерфейс Стратегии
class SortStrategy(ABC):
@abstractmethod
def sort(self, data: List) -> List:
pass
# 2. Конкретные стратегии
class AscendingSort(SortStrategy):
"""Сортировка по возрастанию."""
def sort(self, data: List) -> List:
return sorted(data)
class DescendingSort(SortStrategy):
"""Сортировка по убыванию."""
def sort(self, data: List) -> List:
return sorted(data, reverse=True)
# 3. Контекст
class Sorter:
def __init__(self, strategy: SortStrategy):
self._strategy = strategy
def set_strategy(self, strategy: SortStrategy):
"""Позволяет сменить стратегию на лету."""
self._strategy = strategy
def execute_sort(self, data: List):
print(f"Используется стратегия: {self._strategy.__class__.__name__}")
result = self._strategy.sort(data)
print(f"Результат: {result}")
return result
# Использование
data_to_sort = [5, 2, 8, 1, 9, 4]
# Изначально используем сортировку по возрастанию
sorter = Sorter(AscendingSort())
sorter.execute_sort(data_to_sort)
# Вывод:
# Используется стратегия: AscendingSort
# Результат: [1, 2, 4, 5, 8, 9]
# Динамически меняем стратегию на сортировку по убыванию
sorter.set_strategy(DescendingSort())
sorter.execute_sort(data_to_sort)
# Вывод:
# Используется стратегия: DescendingSort
# Результат: [9, 8, 5, 4, 2, 1]
Преимущества паттерна:
- Гибкость: Позволяет легко добавлять новые алгоритмы, не изменяя код контекста.
- Изоляция: Код, данные и зависимости алгоритмов изолированы в своих классах.
- Следование принципу открытости/закрытости: Система открыта для расширения (новые стратегии), но закрыта для модификации (не нужно менять класс
Sorter).