1 12.1K ru

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

Categories: 💻 Programming

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

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

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

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

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

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

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

pattern strategy uml schema

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

  /// <summary>
    /// The 'Strategy' abstract class
    /// </summary>
    public abstract class Strategy
    {
        public abstract void AlgorithmInterface();
    }

    /// <summary>
    /// A 'ConcreteStrategy' class
    /// </summary>
    public class ConcreteStrategyA : Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine(
              "Called ConcreteStrategyA.AlgorithmInterface()");
        }
    }

    /// <summary>
    /// A 'ConcreteStrategy' class
    /// </summary>
    public class ConcreteStrategyB : Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine(
              "Called ConcreteStrategyB.AlgorithmInterface()");
        }
    }

    /// <summary>
    /// A 'ConcreteStrategy' class
    /// </summary>
    public class ConcreteStrategyC : Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine(
              "Called ConcreteStrategyC.AlgorithmInterface()");
        }
    }

    /// <summary>
    /// The 'Context' class
    /// </summary>
    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<T> или IEqualityComparer<T>, использует паттерн «Стратегия».
  • WCF просто переполнен стратегиями: IErrorHandler — стратегия обработки коммуникационных ошибок; IChannelInitializer — стратегия инициализации канала; IDispatchMessageFormatter — стратегия форматирования сообщений; MessageFilter — стратегия фильтрации сообщений и т. д. Обилие стратегий наблюдается также в Windows Forms, WPF, ASP.NET и других фреймворках.

Comments:

Please log in to be able add comments.
👍