Паттерны проектирования
1. Паттерн «Стратегия» (Strategy). Начало
Паттерн «Стратегия» является настолько распространенным и общепринятым, что многие его используют постоянно, даже не задумываясь об этом. Сортировка, анализ данных, валидация, разбор данных, сериализация, кодирование/декодирование, получение конфигурации — все эти концепции могут и должны быть выражены в виде стратегий или политик (policy).
Назначение: определяет семейство алгоритмов, инкапсулирует каждый из них и делает их взаимозаменяемыми. Стратегия позволяет изменять алгоритмы независимо от клиентов, которые ими пользуются.
Причины использования:
- необходимость инкапсуляции поведения или алгоритма;
- необходимость замены поведения или алгоритма во время исполнения.
Стратегия нужна тогда, когда не просто требуется спрятать алгоритм, а важно иметь возможность заменить его во время исполнения.
Классическая диаграмма приведена на рисунке ниже:
- Strategy — определяет интерфейс алгоритма;
- Context — клиент стратегии;
- ConcreteStrategyA, ConcreteStrategyB,… — конкретные реализации стратегии.
Классический паттерн весьма абстрактен. Он не определяет, каким образом контекст получает экземпляр стратегии, или как стратегия получит данные, необходимые для выполнения своей работы.
Выделение интерфейса
Существуют сторонники и противники выделения интерфейсов. Это относится не только к паттерну Стратегия. Обязательно ли выделять интерфейс
AlgorithmInterface (см. рисунок ниже)? Это зависит от того, нужна ли нам стратегия и хотим ли мы заменять эту стратегию во время исполнения или можем использовать конкретную реализацию и внести в неё изменения в случае необходимости.У выделения интерфейса и передачи его в качестве зависимости есть несколько особенностей. Передача интерфейса классу увеличивает гибкость, но в то же время повышает сложность. Теперь клиентам класса нужно либо решать, какую реализацию использовать, либо переложить эту ответственность на вызывающий код. Важно понимать, нужен ли дополнительный уровень абстракции именно сейчас. Может быть, на текущем этапе достаточно использовать класс напрямую, а выделить интерфейс только тогда, когда в этом действительно появится необходимость.
Продолжение следует…
Источник: Тепляков С. "Паттерны проектирования на платформе .NET." — СПб.: Питер, 2015. Глава 1.