Паттерн стратегия с пример программы

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

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

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

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

Паттерн Стратегия в C#

C++. Паттерн проектирования программ «Стратегия (Strategy)».

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

public interface IStrategy < void Algorithm(); >public class ConcreteStrategy1 : IStrategy < public void Algorithm() <>> public class ConcreteStrategy2 : IStrategy < public void Algorithm() <>> public class Context < public IStrategy ContextStrategy < get; set; >public Context(IStrategy _strategy) < ContextStrategy = _strategy; >public void ExecuteAlgorithm() < ContextStrategy.Algorithm(); >>

Участники

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

  • Интерфейс IStrategy, который определяет метод Algorithm() . Это общий интерфейс для всех реализующих его алгоритмов. Вместо интерфейса здесь также можно было бы использовать абстрактный класс.
  • Классы ConcreteStrategy1 и ConcreteStrategy, которые реализуют интерфейс IStrategy, предоставляя свою версию метода Algorithm() . Подобных классов-реализаций может быть множество.
  • Класс Context хранит ссылку на объект IStrategy и связан с интерфейсом IStrategy отношением агрегации.

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

Читайте также:
Можно ли установить программы на съемный жесткий диск

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

class Program < static void Main(string[] args) < Car auto = new Car(4, «Volvo», new PetrolMove()); auto.Move(); auto.Movable = new ElectricMove(); auto.Move(); Console.ReadLine(); >> interface IMovable < void Move(); >class PetrolMove : IMovable < public void Move() < Console.WriteLine(«Перемещение на бензине»); >> class ElectricMove : IMovable < public void Move() < Console.WriteLine(«Перемещение на электричестве»); >> class Car < protected int passengers; // кол-во пассажиров protected string model; // модель автомобиля public Car(int num, string model, IMovable mov) < this.passengers = num; this.model = model; Movable = mov; >public IMovable Movable < private get; set; >public void Move() < Movable.Move(); >>

В данном случае в качестве IStrategy выступает интерфейс IMovable, определяющий метод Move() . А реализующий этот интерфейс семейство алгоритмов представлено классами ElectricMove и PetroleMove. И данные алгоритмы использует класс Car.

Важнейший шаблон программирования из 23-х

Источник: metanit.com

Паттерн «Стратегия» (Strategy)

Паттерн «Стратегия» (Strategy)

Назначение: определяет семейство алгоритмов, инкапсулирует каждый из них и делает их взаимозаменяемыми. Стратегия позволяет изменять алгоритмы независимо от клиентов, которые ими пользуются.
Другими словами: стратегия инкапсулирует определенное поведение с возможностью его подмены.

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

  • Когда есть несколько схожих классов , которые отличаются поведением. Можно задать один основной класс, а разные варианты поведения вынести в отдельные классы и при необходимости их применять;
  • Когда необходимо обеспечить выбор из нескольких вариантов решений, которые можно легко менять в зависимости от условий;
  • Когда необходимо менять поведение классов и объектов на стадии выполнения программы;
  • Когда класс, применяющий определенную функциональность, ничего не должен знать о ее реализации

Паттерн «стратегия» можно выразить на схеме UML таким образом:

pattern strategy uml schema

Реализация схемы на языке C#

/// /// The ‘Strategy’ abstract class /// public abstract class Strategy < public abstract void AlgorithmInterface(); >/// /// A ‘ConcreteStrategy’ class /// public class ConcreteStrategyA : Strategy < public override void AlgorithmInterface() < Console.WriteLine( «Called ConcreteStrategyA.AlgorithmInterface()»); >> /// /// A ‘ConcreteStrategy’ class /// public class ConcreteStrategyB : Strategy < public override void AlgorithmInterface() < Console.WriteLine( «Called ConcreteStrategyB.AlgorithmInterface()»); >> /// /// A ‘ConcreteStrategy’ class /// public class ConcreteStrategyC : Strategy < public override void AlgorithmInterface() < Console.WriteLine( «Called ConcreteStrategyC.AlgorithmInterface()»); >> /// /// The ‘Context’ class /// public class Context < private readonly Strategy _strategy; // Constructor public Context(Strategy strategy) < _strategy = strategy; >public void ContextInterface() < _strategy.AlgorithmInterface(); >>

Читайте также:
Программа что набирали на клавиатуре

Участники:

Из диаграммы и кода можно выделить таких участников:

  • Абстрактный класс Strategy (он может быть заменен интерфейсом), который определяет метод AlgorithmInterface() .
  • Классы ConcreteStrategyA и ConcreteStrategyB, ConcreteStrategyC, которые реализуют Strategy, предоставляя переопределяя метод AlgorithmInterface() . Подобных классов-реализаций может быть множество.
  • Класс Context хранит ссылку на объект Strategy и связан с абстрактным классом Strategy отношением агрегации.

Неформальная схема паттерна выглядит вот так:

pattern strategy easy schema

Примеры реализации в .net framework

Паттерн стратегия очень распространенный паттерн в фреймворке:

  • LINQ (Language Integrated Query) — это набор методов расширения, принимающих стратегии фильтрации, получения проекции и т. д. Коллекции принимают стратегии сравнения элементов, а значит, любой класс, который принимает IComparer или IEqualityComparer, использует паттерн «Стратегия».
  • WCF просто переполнен стратегиями: IErrorHandler — стратегия обработки коммуникационных ошибок; IChannelInitializer — стратегия инициализации канала; IDispatchMessageFormatter — стратегия форматирования сообщений; MessageFilter — стратегия фильтрации сообщений и т. д. Обилие стратегий наблюдается также в Windows Forms, WPF, ASP.NET и других фреймворках.

Источник: bool.dev

Паттерн Strategy (стратегия)

Существуют системы, поведение которых может определяться согласно одному алгоритму из некоторого семейства. Все алгоритмы этого семейства являются родственными: предназначены для решения общих задач, имеют одинаковый интерфейс для использования и отличаются только реализацией (поведением). Пользователь, предварительно настроив программу на нужный алгоритм (выбрав стратегию), получает ожидаемый результат. Как пример, — приложение, предназначенное для компрессии файлов использует один из доступных алгоритмов: zip, arj или rar.

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

UML-диаграмма классов. Программа сжатия файлов. Стандартный подход на основе полиморфизма

Представленному подходу свойственны следующие недостатки:

  1. Реализация алгоритма жестко привязана к его подклассу, что затрудняет поддержку и расширение такой системы.
  2. Система, построенная на основе наследования, является статичной. Заменить один алгоритм на другой в ходе выполнения программы уже невозможно.
Читайте также:
Как отменить программу 2100

Применение паттерна Strategy позволяет устранить указанные недостатки.

Описание паттерна Strategy

Паттерн Strategy переносит в отдельную иерархию классов все детали, связанные с реализацией алгоритмов. Для случая программы сжатия файлов абстрактный базовый класс Compression этой иерархии объявляет интерфейс, общий для всех алгоритмов и используемый классом Compressor. Подклассы ZIP_Compression, ARJ_Compression и RAR_Compression его реализуют в соответствии с тем или иным алгоритмом. Класс Compressor содержит указатель на объект абстрактного типа Compression и предназначен для переадресации пользовательских запросов конкретному алгоритму. Для замены одного алгоритма другим достаточно перенастроить этот указатель на объект нужного типа.

UML-диаграмма классов. Программа сжатия файлов. Использование паттерна Strategy

Структура паттерна Strategy

UML-диаграмма классов паттерна Strategy

UML-диаграмма классов паттерна Strategy

Реализация паттерна Strategy

Приведем реализацию приложения для сжатия файлов, спроектированного с применением паттерна Strategy.

#include #include // Иерархия классов, определяющая алгоритмы сжатия файлов class Compression < public: virtual ~Compression() <>virtual void compress( const string >; class ZIP_Compression : public Compression < public: void compress( const string cout >; class ARJ_Compression : public Compression < public: void compress( const string cout >; class RAR_Compression : public Compression < public: void compress( const string cout >; // Класс для использования class Compressor < public: Compressor( Compression* comp): p(comp) <>~Compressor() < delete p; >void compress( const string p->compress( file); > private: Compression* p; >; int main() < Compressor* p = new Compressor( new ZIP_Compression); p->compress( «file.txt»); delete p; return 0; >

Результаты применения паттерна Strategy

Достоинства паттерна Strategy

  • Систему проще поддерживать и модифицировать, так как семейство алгоритмов перенесено в отдельную иерархию классов.
  • Паттерн Strategy предоставляет возможность замены одного алгоритма другим в процессе выполнения программы.
  • Паттерн Strategy позволяет скрыть детали реализации алгоритмов от клиента.

Недостатки паттерна Strategy

  • Для правильной настройки системы пользователь должен знать об особенностях всех алгоритмов.
  • Число классов в системе, построенной с применением паттерна Strategy, возрастает.

Источник: cpp-reference.ru

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru