В этой статье будет рассмотрен паттерн проектирования Стратегия C# — Strategy C#, для чего он нужен и какие проблемы он решает, где можно применять данный шаблон и когда это будет излишним.
Идея паттерна Стратегия (Strategy)
Паттерн проектирования — это продуманный способ построения исходного кода программы для решения часто возникающих в повседневном программировании проблем проектирования. Иными словами, это уже придуманное решения, для типичной задачи. При этом паттерн не готовое решение, а просто алгоритм действий, который должен привести к желаемому результату. Давайте рассмотрим один из наиболее часто используемых поведенческих паттернов — Стратегия (Strategy).
Как я уже писал ранее, существует три вида паттернов проектирования:
- Порождающие паттерны позволяют возможность выполнять инициализацию объектов наиболее удобным и оптимальным способом.
- Структурные паттерны описывают взаимоотношения между различными классами или объектами, позволяя им совместно реализовывать поставленную задачу.
- Поведенческие паттерны позволяют грамотно организовать связь между сущностями для оптимизации и упрощения их взаимодействия.
Стратегия (Strategy) — это поведенческий паттерн, который позволяет инкапсулировать группу взаимосвязанных алгоритмов, и при необходимости заменять их друг на друга, без привязки к конкретным пользователям. То есть, Стратегия позволяет скрыть часть логики, предоставив возможность ее изменения.
Подпишись на группу Вконтакте и Телеграм-канал. Там еще больше полезного контента для программистов.
А на YouTube-канале ты найдешь обучающие видео по программированию. Подписывайся!
Архитектура паттерна проектирования Стратегия

- Strategy — интерфейс алгоритма
- Context — клиент стратегии
- ConcreteStrategyA, ConcreteStrategyB, ConcreteStrategyC — конкретные реализации стратегии
Логика работы паттерна Strategy
Рассмотрим основную логику работы паттерна Стратегия. На самом деле данное поведение настолько часто встречается в повседневном программировании, что мы даже не задумываемся о том, что используем данный паттерн проектирования. Когда мы выделяем интерфейс, мы уже пользуемся стратегией, когда используем наследование тоже. Основная идея заключается в том, что мы определяем интерфейс, а реализуем его отдельно.
Реализация шаблона Стратегия (Strategy) на языке C#
Давайте рассмотрим тривиальный пример реализации данного паттерна. Мы зададим стратегию вывода текста на консоль. А конкретные реализации будут выводить текст разным цветом. Для этого определим интерфейс IConsoleWriter
namespace Strategy { /// <summary> /// Интерфейс стратегии. /// </summary> public interface IConsoleWriter { /// <summary> /// Вывод текста на консоль. /// </summary> /// <param name="text"> Выводимый текст. </param> void WriteText(string text); } }
Теперь создадим три класса, которые будут реализовывать данный интерфейс
using System; namespace Strategy { /// <summary> /// Реализация стратегии вывода текста синим цветом. /// </summary> public class BlueConsoleWriter : IConsoleWriter { /// <summary> /// Вывод текста на консоль. /// </summary> /// <param name="text"> Выводимый текст. </param> public void WriteText(string text) { // Проверяем входные данные на корректность. if(string.IsNullOrWhiteSpace(text)) { throw new ArgumentNullException(nameof(text)); } // Устанавливаем синий цвет. Console.ForegroundColor = ConsoleColor.Blue; // Выводим на консоль. Console.WriteLine(text); } } }
using System; namespace Strategy { /// <summary> /// Реализация стратегии вывода текста зеленым цветом. /// </summary> public class GreenConsoleWriter : IConsoleWriter { /// <summary> /// Вывод текста на консоль. /// </summary> /// <param name="text"> Выводимый текст. </param> public void WriteText(string text) { // Проверяем входные данные на корректность. if (string.IsNullOrWhiteSpace(text)) { throw new ArgumentNullException(nameof(text)); } // Устанавливаем зеленый цвет. Console.ForegroundColor = ConsoleColor.Green; // Выводим на консоль. Console.WriteLine(text); } } }
using System; namespace Strategy { /// <summary> /// Реализация стратегии вывода текста красным цветом. /// </summary> public class RedConsoleWriter : IConsoleWriter { /// <summary> /// Вывод текста на консоль. /// </summary> /// <param name="text"> Выводимый текст. </param> public void WriteText(string text) { // Проверяем входные данные на корректность. if (string.IsNullOrWhiteSpace(text)) { throw new ArgumentNullException(nameof(text)); } // Устанавливаем красный цвет. Console.ForegroundColor = ConsoleColor.Red; // Выводим на консоль. Console.WriteLine(text); } } }
Ну и наконец создадим клиента, который будет работать со стратегией, обращаясь к ее конкретным реализациям.
using System; using System.Threading; namespace Strategy { class Program { static void Main(string[] args) { // Задаем количество строк, которые будут выведены на экран. var count = 25; // Задаем задержку между выводом сообщений на консоль. var delay = TimeSpan.FromSeconds(1); // Создаем коллекцию из конкретных реализаций стратегии. // Обратите внимание, что мы используем тип IConsoleWriter, // что позволяет разместить в эту коллекцию любой класс, // который реализует данный интерфейс стратегии. var writers = new IConsoleWriter[] { new RedConsoleWriter(), new BlueConsoleWriter(), new GreenConsoleWriter() }; // Простой цикл, чтобы вывести на консоль текст заданное количество раз. for(var i = 0; i < count; i++) { // Получаем индекс элемента из коллекции остатком от деления // текущего номера итерации на общее количество элементов в коллекции. var index = i % writers.Length; // Получаем конкретную реализацию стратегии. var writer = writers[index]; // Подготавливаем случайный текст, который будет выведен на экран. var text = Guid.NewGuid().ToString(); // Выводим текст конкретной реализацией стратегии. writer.WriteText(text); // Ждем заданный промежуток времени, чтобы выполнялось не слишком быстро. Thread.Sleep(delay); } // Ждем завершения. Console.ReadLine(); } } }
Получаем следующий результат работы приложения

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