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

Это позволяет выбирать алгоритм путем определения соответствующего класса.

Шаблон Strategy позволяет менять выбранный алгоритм независимо от объектов клиентов, которые его используют.

 

Проблема: по типу клиента (или по типу обрабатываемых данных) выбрать подходящий алгоритм, который следует применить.

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

Решение: отделение процедуры выбора алгоритма от его реализации.

Это позволяет сделать выбор на основании контекста.

 

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

- Конкретные классы ConcreteStrategy реализуют эти различные алгоритмы.

- Класс Context использует конкретные классы ConcreteStrategy посредством ссылки на конкретный тип абстрактного класса Strategy.

- Классы Strategy и Context взаимодействуют с целью реализации выбранного алгоритма (в некоторых случаях классу Strategy требуется посылать запросы классу Context).

- Класс Context пересылает классу Strategy запрос, поступивший от его класса клиента.

 

Этот паттерн инкапсулирует семейство алгоритмов, делая их взаимозаменяемыми.

Применять его целесообразно в следующих случаях:

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

• Требуется иметь несколько разных вариантов алгоритма.

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

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

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

Инкапсулированные алгоритмы можно затем применять в разных контекстах;

• в алгоритме хранятся данные, о которых клиент не должен «знать». Стратегия позволяет не раскрывать сложные, специфичные для алгоритма структуры данных;

• в классе определено много вариантов поведения, что представлено разветвленными условными операторами. В этом случае проще перенести код из ветвей в отдельные классы стратегий.

Структура паттерна приведена на рис.

Паттерн состоит из следующих классов:

Strategy (стратегия) объявляет общий для всех поддерживаемых алгоритмов интерфейс.

Класс Context пользуется этим интерфейсом для вызова конкретного алгоритма, определенного в классе ConcreteStrategy;

ConcreteStrategy (конкретная стратегия) — наследник класса Strategy. Реализует алгоритм, использующий интерфейс, объявленный в классе Strategy;

Context (контекст) конфигурируется объектом класса ConcreteStrategy.

Хранит ссылку на объект класса Strategy и может определять интерфейс, который позволяет объекту Strategy получить доступ к данным контекста.

Таким образом, объект Context делегирует реализацию конкретного алгоритма поведения объекту Strategy, что дает возможность гибко изменять поведение объекта.

#include <iostream>

Class Strategy

{ public:

    virtual ~Strategy() {}

    virtual void use(void) = 0;

};

Class Strategy_1: public Strategy

{

public:

    void use(void){ std::cout << "Strategy_1" << std::endl; };

};

Class Strategy_2: public Strategy

{

public:

    void use(void){ std::cout << "Strategy_2" << std::endl; };

};

Class Strategy_3: public Strategy

{

public:

    void use(void){ std::cout << "Strategy_3" << std::endl; };

};

Class Context

{ protected:

    Strategy* operation;

public:

    virtual ~Context() {}

    virtual void useStrategy(void) = 0;

    virtual void setStrategy(Strategy* v) = 0;

};


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: