Что такое паттерн "Стратегия" (Strategy)
Стратегия — поведенческий паттерн проектирования, который позволяет выбирать алгоритм поведения объекта во время выполнения. Вместо жёстко прописанного алгоритма, объект делегирует задачу одному из семейства алгоритмов.
Представьте, что у вас есть приложение, которое может сортировать данные разными способами: быстрой сортировкой, сортировкой слиянием или пузырьком. Паттерн Стратегия позволяет легко переключать алгоритмы сортировки без изменения клиента.
Преимущества паттерна «Стратегия»
- Изоляция алгоритмов, упрощение их замены и расширения.
- Упрощение поддержки и тестирования каждого алгоритма отдельно.
- Повышение гибкости системы.
Пример:
- Контекст — объект, который использует алгоритм.
- Стратегии — отдельные классы, реализующие разные алгоритмы.
- Контекст делегирует выполнение задачи выбранной стратегии.
Где применяется паттерн «Стратегия»?
- При выборе алгоритма на основе условий во время выполнения.
- В системах с вариативными бизнес-правилами.
- Для замены условных операторов выбора поведения.
Пример реализации на JavaScript
// Интерфейс стратегии class Strategy { execute(data) { throw new Error("Метод execute() должен быть реализован"); } } // Конкретные стратегии class BubbleSortStrategy extends Strategy { execute(data) { console.log("Сортировка пузырьком"); // Пример простой сортировки пузырьком for (let i = 0; i < data.length; i++) { for (let j = 0; j < data.length - i - 1; j++) { if (data[j] > data[j + 1]) { [data[j], data[j + 1]] = [data[j + 1], data[j]]; } } } return data; } } class QuickSortStrategy extends Strategy { execute(data) { console.log("Быстрая сортировка"); if (data.length <= 1) return data; const pivot = data[0]; const left = data.slice(1).filter((el) => el < pivot); const right = data.slice(1).filter((el) => el >= pivot); return [...this.execute(left), pivot, ...this.execute(right)]; } } // Контекст class Sorter { constructor(strategy) { this.strategy = strategy; } setStrategy(strategy) { this.strategy = strategy; } sort(data) { return this.strategy.execute(data); } } // Использование const sorter = new Sorter(new BubbleSortStrategy()); console.log(sorter.sort([5, 3, 8, 1])); sorter.setStrategy(new QuickSortStrategy()); console.log(sorter.sort([5, 3, 8, 1]));
Когда стоит использовать паттерн «Стратегия»?
- Когда нужно менять алгоритмы во время выполнения.
- Чтобы избежать большого количества условных операторов.
- Для инкапсуляции алгоритмов и повышения гибкости.
Отличие от других паттернов
- В отличие от Шаблонного метода, Стратегия делегирует весь алгоритм отдельным классам.
- Отличается от Состояния тем, что выбор стратегии обычно контролируется клиентом, а не внутренним состоянием объекта.
Плюсы паттерна
- Улучшает читаемость и расширяемость кода.
- Легко добавлять новые алгоритмы.
- Способствует принципу открытости/закрытости (OCP).
Минусы паттерна
- Увеличивает количество классов.
- Клиент должен знать о различных стратегиях.