для чего нужен паттерн strategy

Pattern Strategy C# | Паттерн Стратегия C#

В этой статье будет рассмотрен паттерн проектирования Стратегия C# — Strategy C#, для чего он нужен и какие проблемы он решает, где можно применять данный шаблон и когда это будет излишним.

Идея паттерна Стратегия (Strategy)

Паттерн проектирования — это продуманный способ построения исходного кода программы для решения часто возникающих в повседневном программировании проблем проектирования. Иными словами, это уже придуманное решения, для типичной задачи. При этом паттерн не готовое решение, а просто алгоритм действий, который должен привести к желаемому результату. Давайте рассмотрим один из наиболее часто используемых поведенческих паттернов — Стратегия (Strategy).

Как я уже писал ранее, существует три вида паттернов проектирования:

Стратегия (Strategy) — это поведенческий паттерн, который позволяет инкапсулировать группу взаимосвязанных алгоритмов, и при необходимости заменять их друг на друга, без привязки к конкретным пользователям. То есть, Стратегия позволяет скрыть часть логики, предоставив возможность ее изменения.

Архитектура паттерна проектирования Стратегия

для чего нужен паттерн strategy

Логика работы паттерна Strategy

Рассмотрим основную логику работы паттерна Стратегия. На самом деле данное поведение настолько часто встречается в повседневном программировании, что мы даже не задумываемся о том, что используем данный паттерн проектирования. Когда мы выделяем интерфейс, мы уже пользуемся стратегией, когда используем наследование тоже. Основная идея заключается в том, что мы определяем интерфейс, а реализуем его отдельно.

Реализация шаблона Стратегия (Strategy) на языке C#

Давайте рассмотрим тривиальный пример реализации данного паттерна. Мы зададим стратегию вывода текста на консоль. А конкретные реализации будут выводить текст разным цветом. Для этого определим интерфейс IConsoleWriter

Теперь создадим три класса, которые будут реализовывать данный интерфейс

Ну и наконец создадим клиента, который будет работать со стратегией, обращаясь к ее конкретным реализациям.

Получаем следующий результат работы приложения

для чего нужен паттерн strategy

Исходный код приложения можно скачать из репозитория github https://github.com/shwanoff/Strategy

Также рекомендую изучить Паттерн Посредник (Mediator). А еще подписывайтесь на группу ВКонтакте, Telegram и YouTube-канал. Там еще больше полезного и интересного для программистов.

Источник

«Strategy Pattern. Просто о простом» или почему я хожу на собеседования «PHP Junior» ради fun’а

Приветствие

В этот раз меня посетило несколько другое чувство, и, как я убедился, не только меня. Чувство это напомнило мне об одном из моих собеседований, где меня попросили написать скелет паттерна «Декоратор», который оказался в личном представлении интервьювера совершенно другим, нежели его классическое толкование.

Дабы не разочаровать и не ввести мозг читателя в «когнитивный диссонанс» уточню, что в этой статье пойдет речь о «гипотетическом» собеседовании в этой компании, так, если бы меня попросили рассказать о паттерне «Стратегия». Как и в предыдущем случае, мой ответ выглядел бы в глазах интервьювера как минимум сомнительно.

Не подглядывать

Зная, что в электронной кладези знаний стопроцентно имеется статья «Шаблон проектирования Стратегия», с примером на C++, который скорее всего взят из книжки GoF, и на всех известных языках программирования (а вдруг и включая эзотерические), моей задачей стало: не подглядывая, упихать схожий пример из статьи в концепцию паттерна. Поглядим, что нужно сделать и что получилось.

Пилите, Шура, пилите

На мой взгляд, оперировать конкретными типами классов, не есть хорошо: в данном случа мы обладаем не только знанием о интерфейсе класса, но и о реализации, включаещей обычно ворох дополнительных методов (часто открытых === public). Вместо этого, предлагается подход, основанный на интерфейсах, так что первым шагом рефакторинга примера будет выделение оных:

А адаптация нашего желания для валидации, например, имени пользователя будет выглядеть следующим образом:

«Согласен», отвечу я тебе, внимательный читатель, на твой незримый вопрос:

Каждый раз вызывается конструктор? Может синглтон или статичная переменная функции, не?

Но это уже вопросы следующего рефакторинга. Вернемся к предметной области примера: нам понадобится сущности для валидации, к примеру, почтового ящика (email), и отвечающие на вопросы: этот адрес Hoho? этот адрес не слишком короткий или длинный?

Так, как наша функция Validate() не позволяет использовать коллекцию (список, массив) валидаторов, то придется расширить её функционал использованием коллекции (списка, массива) валидаторов как аргумента:

Источник

Strategy Design Pattern

Всем привет, друзья. Меня зовут Alex, я профессиональный разработчик и создатель программных продуктов в веб индустрии. Много лет изучаю языки, делюсь опытом с другими.

Сегодня хочу с вами поговорить про шаблон проектирования Стратегия (Strategy). Постараюсь донести до вас принципы и суть шаблона без воды, и покажу как его применять на практике.

В чем суть?

Шаблон дает возможность в процессе выполнения выбрать стратегию (алгоритм, инструмент, подход) решения задачи.

В чем проблема?

Рассмотрим задачи, при решении которых можно применять такой подход.

Выбрать область на карте, где покупатель желает приобрести жилье

И указать ценовой диапазон цен на квартиры для фильтрации.

Первая версия вашего портала отлично справилась с поставленной задачей и пользователи могли без проблем искать, сужая свой поиск квартир по ценовом диапазону и выбранной географической области на карте. Ну и конечно вы хорошо постарались, как разработчик и все правильно сделали на ваш взгляд с точки зрения архитектуры кода, реализовали классы, которые ищет квартиры на продажу в вашей базе.

Если функционал поиска и фильтрации с квартирами на продажу было довольно легко реализовать, то любые новые изменения вызывали много вопросов и головную боль по архитектуре. Пришлось очень многое менять в коде. Вы понимали, что любое изменение алгоритмов выдачи нужных квартир и элементов для отображения затрагивает основные базовые классы, в которых реализован весь функционал фильтрации. Основной функционал поиска квартир изначально был реализован в одном классе, при добавлении нового функционала этот класс разрастался, вы добавляли новые условия, новые ветвления, новые методы и функции.

Изменение такого класса, даже в случае исправление багов, сильно повышает риск сделать новые ошибки. Над данным функционалом работала целая команда разработчиков, любые изменения в итоге проходили долгую обкатку и тестирование, а изменения, добавляемые другими программистами в базовые классы, создавала новые проблемы и конфликты, релизы затягивались. Вы столкнулись со следующими проблемами:

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

Алгоритм выбора и отображения элементов интерфейса был реализован в одном супер-классе

Изменения в этих классах, сделанные разными программистами, приводили к конфликтам и необходимости регрессивного тестирования

Релизы продукта затягивались, время на разработку нового функционала увеличилась в несколько раз

Больше времени стало уходить на разработку, тестирование, появилось множество багов.

для чего нужен паттерн strategyСупер-класс с единым методом реализации алгоритма.

Какое решение?

В данном примере мы имеем несколько алгоритмов для одной функции:

Поиск квартир с продажей

Поиск квартир в аренду

Отображение или нет различных наборов фильтров

Чтобы работа нашего класса была одинаковой для разного поведения, у объектов-стратегии должен быть общий интерфейс. Используя такой интерфейс вы делаете независимым наш класс-контекста от классов-стратегий.

для чего нужен паттерн strategyДиаграмма классов шаблона Strategy

Возвращаясь к нашему примеру с порталом по поиску недвижимости, мы должны вынести алгоритмы поиска недвижимости на продажу и аренду в отдельные классы-стратегии, где реализовать конкретные алгоритмы по поиску разных типов объектов. Аналогичное можно проделать и с классами работы с элементами интерфейса для различных видов пользователей.

Пример реализации

для чего нужен паттерн strategyStrategy.go

для чего нужен паттерн strategyFirstAlgorithm.go для чего нужен паттерн strategySecondAlgorithm.go

Посмотрим на нашу диаграмму классов. Нам осталось реализовать класс-контекста и клиентский код вызова конкретных алгоритмов в нужным момент. Как это сделать? Для создания слоя класса-контекста реализуем исходник, реализующий:

определяемый тип в базовым типом struct

для чего нужен паттерн strategyContext.go

для чего нужен паттерн strategyClient.go

Вот вывод такого подхода:

First implements strategy map[role:1]

Second implements strategy map[role:2]

Как видите, мы можем управлять вызовом разных алгоритмов в зависимости от контекста и пользовательских фильтров. Алгоритмы могут создавать ветвления в зависимости от входных фильтров и других параметров, переданных из клиентского кода в методы, реализующие конкретные алгоритмы. Вот такой интересный пример.

Объектно-ориентированный подход можно посмотреть. например, в этом курсе. Там показан пример на PHP.

Когда применять?

Напоследок поговорим когда применяется шаблон Strategy?

У вас есть множество похожих реализаций отличающихся незначительным поведением. Можно вынести отличающее поведение в классы-стратегии, а повторяющий код свести к единому классу-контекста.

Ваш алгоритм реализован в супер-классе с множественными условными операторами. Выделите блоки условных операторов в отдельные классы-стратегии, а управление вызовов нужных доверьте классу-контекста.

Конкретные стратегии позволяют инкапсулировать алгоритмы в своих конкретных классах. Используйте этот подход для снижения зависимостей от других классов.

В зависимости от ситуации вы можете менять стратегию выполнения задачи в процессе выполнения программы. Например, в зависимости от скорости интернета использовать разные стратегии-поведения, возвращающие разный набор данных для отображения страницы.

Подведем итог

Друзья, мы познакомились с поведенческим шаблоном проектирования Strategy. Шаблон используется для выделения схожих алгоритмов, решающих конкретную задачу. Посмотрели с вами реализацию на языке GOlang, ознакомились в возможностями подхода и разобрали когда его лучше применять.

Рад был с вами пообщаться, Alex Versus. Успехов!

Источник

Паттерны поведения

Стратегия (Strategy)

Паттерн Стратегия (Strategy) представляет шаблон проектирования, который определяет набор алгоритмов, инкапсулирует каждый из них и обеспечивает их взаимозаменяемость. В зависимости от ситуации мы можем легко заменить один используемый алгоритм другим. При этом замена алгоритма происходит независимо от объекта, который использует данный алгоритм.

Когда использовать стратегию?

Когда есть несколько родственных классов, которые отличаются поведением. Можно задать один основной класс, а разные варианты поведения вынести в отдельные классы и при необходимости их применять

Когда необходимо обеспечить выбор из нескольких вариантов алгоритмов, которые можно легко менять в зависимости от условий

Когда необходимо менять поведение объектов на стадии выполнения программы

Когда класс, применяющий определенную функциональность, ничего не должен знать о ее реализации

Формально паттерн Стратегия можно выразить следующей схемой UML:

для чего нужен паттерн strategy

Формальное определение паттерна на языке C# может выглядеть следующим образом:

Участники

Как видно из диаграммы, здесь есть следующие участники:

Класс Context хранит ссылку на объект IStrategy и связан с интерфейсом IStrategy отношением агрегации.

В данном случае объект IStrategy заключена в свойстве ContextStrategy, хотя также для нее можно было бы определить приватную переменную, а для динамической установки использовать специальный метод.

Теперь рассмотрим конкретный пример. Существуют различные легковые машины, которые используют разные источники энергии: электричество, бензин, газ и так далее. Есть гибридные автомобили. В целом они похожи и отличаются преимущественно видом источника энергии. Не говоря уже о том, что мы можем изменить применяемый источник энергии, модифицировав автомобиль. И в данном случае вполне можно применить паттерн стратегию:

Источник

Паттерн Стратегия на Javascript

Далее мы разберём примеры того, как я использую СТРАТЕГИЮ в Javascript, и как он используется реальной библиотекой, для разбиения её на небольшие части.

Далее мы разберём примеры того, как я использую СТРАТЕГИЮ в Javascript, и как он используется реальной библиотекой, для разбиения её на небольшие части.

Стратегия как функция

Проиллюстрируем это на примере. Допустим, мы хотим создать класс Greeter. Его задача — приветствовать людей. А так же мы хотим, чтобы Greeter умел приветствовать их по-разному. То есть, нам нужно несколько разных реализаций алгоритма. Для этого мы создадим различные стратегии приветствия. Здесь и далее, под алгоритмом подразумевается приветствие.
В этом коде есть ошибка (спасибо bashtannik). Так как в алгоритмах стратегий уже заложен вывод в консоль, а метод greet возвращает функцию, не возвращающую ничего — последние три строки следует заменить на

В приведенном выше примере мы создали клиент Greeter и три различных стратегии. Очевидно, что Greeter знает, как использовать алгоритм, но понятия не имеет о том, что у него под капотом.

Но для сложных алгоритмов, функции зачастую бывает недостаточно. В этом случае, лучше использовать СТРАТЕГИЮ в ООП стиле.

Стратегия как класс

Стратегиями так же могут быть и классы, особенно в случаях, когда алгоритмы сложнее, чем выдуманный в приведенном выше примере. Использование классов позволяет определить интерфейс для каждой стратегии.

Рассмотрим это на примере.

Мы определили Strategy как объект (или класс) с методом execute. Клиент может использовать любую стратегию, которая соответствует этому классу.

Обратите внимание на GreetingStrategy. Самое интересное находится в переопределении метода execute. Он зависит от других методов этого класса. Теперь объекты, унаследовавшие этот класс, могут изменять отдельные методы, такие как sayHi или sayBye, без изменения основного алгоритма. Этот паттерн называется Шаблонный метод и он прекрасно сочетается со СТРАТЕГИЕЙ.

Давайте посмотрим, как.
Определив метод execute, GreetingStrategy создаёт семейство алгоритмов. В приведенном выше фрагменте, мы воспользовались этим, создав несколько их разновидностей.

СТРАТЕГИЯ в реальном коде

Один из моих любимых примеров использования СТРАТЕГИИ — библиотека Passport.js.

Passport.js предоставляет простой способ управления аутентификацией в node.js. Она поддерживает большое число провайдеров (Facebook, Twitter, Google и др.), каждый из которых представлен в виде отдельной стратегии.

Библиотека доступна в виде npm-пакета, так же как и все её стратегии. Программист волен решать, какой npm-пакет устанавливать в данном конкретном случае. Вот фрагмент кода, который наглядно показывает, как это работает:
Библиотека Passport.js сама по себе содержит только пару простых механизмов аутентификации. В ней нет ничего, кроме них и Контекста. Эта архитектура позволяет сторонним программистам легко реализовывать свои собственные механизмы аутентификации, не загромождая проект.

Мораль

Источник


Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *