Как это работает, для чего оно используется и когда нужно его использовать?
Как работает шаблон стратегии?
Ответ 1
Давайте объясним шаблон стратегии простым способом:
У вас есть класс Car()
с методом run()
, поэтому вы используете его таким образом на псевдоязыке:
mycar = new Car()
mycar.run()
Теперь вы можете изменить поведение run()
на лету во время выполнения программы. Например, вы можете имитировать отказ двигателя или использовать кнопку "повышения" в видеоигре.
Есть несколько способов сделать это моделирование: использование условных операторов и переменной флага - один из способов. Другой шаблон стратегии: он делегирует поведение метода run()
другому классу:
Class Car()
{
this.motor = new Motor(this)
// passing "this" is important for the motor so it knows what it is running
method run()
{
this.motor.run()
}
method changeMotor(motor)
{
this.motor = motor
}
}
Если вы хотите изменить поведение автомобиля, вы можете просто изменить мотор. (Легче в программе, чем в реальной жизни, верно? ;-))
Это очень полезно, если у вас много сложных состояний: вы можете изменять и поддерживать их гораздо проще.
Ответ 2
Проблема
Шаблон стратегии используется для решения проблем, которые могут (или предполагается, что они могут быть) реализованы или решены различными стратегиями и которые имеют четко определенный интерфейс для таких случаев. Каждая стратегия совершенно полезна сама по себе, при этом некоторые стратегии предпочтительнее в определенных ситуациях, которые позволяют приложению переключаться между ними во время выполнения.
Пример кода
namespace StrategyPatterns
{
// Interface definition for a Sort algorithm
public interface ISort
{
void Sort(List<string> list)
}
// QuickSort implementation
public class CQuickSorter : ISort
{
void Sort(List<string> list)
{
// Here will be the actual implementation
}
}
// BubbleSort implementation
public class CBubbleSort : ISort
{
void Sort(List<string> list)
{
// The actual implementation of the sort
}
}
// MergeSort implementation
public class CMergeSort : ISort
{
void Sort(List<string> list)
{
// Again the real implementation comes here
}
}
public class Context
{
private ISort sorter;
public Context(ISort sorter)
{
// We pass to the context the strategy to use
this.sorter = sorter;
}
public ISort Sorter
{
get{return sorter;)
}
}
public class MainClass
{
static void Main()
{
List<string> myList = new List<string>();
myList.Add("Hello world");
myList.Add("Another item");
myList.Add("Item item");
Context cn = new Context(new CQuickSorter());
// Sort using the QuickSort strategy
cn.Sorter.Sort(myList);
myList.Add("This one goes for the mergesort");
cn = new Context(new CMergeSort());
// Sort using the merge sort strategy
cn.Sorter.Sort(myList);
}
}
}
Ответ 3
- Что такое стратегия? Стратегия - это план действий, предназначенный для достижения конкретной цели;
- "Определите семейство алгоритмов, инкапсулируйте каждый из них и сделайте их взаимозаменяемыми. Стратегия позволяет алгоритму независимо от клиентов, которые его используют". (Банда четырех);
- Определяет набор классов, каждый из которых представляет потенциальное поведение. Переключение между этими классами изменяет поведение приложения. (Стратегия);
- Это поведение можно выбрать во время выполнения (с использованием полиморфизма) или времени разработки;
- Захватить абстракцию в интерфейсе, похоронить детали реализации в производных классах;
- Альтернативой Стратегии является изменение поведения приложения с использованием условной логики. (БАД);
-
Использование этого шаблона упрощает добавление или удаление определенного поведения без необходимости повторного и повторного тестирования всех или частей приложения;
-
Хорошее использование:
- Когда у нас есть набор подобных алгоритмов и его необходимость переключаться между ними в разных частях приложения. С шаблоном стратегии можно избежать ifs и облегчить обслуживание;
- Когда мы хотим добавить новые методы в суперкласс, который не обязательно имеет смысл для каждого подкласса. Вместо традиционного использования интерфейса, добавляя новый метод, мы используем переменную экземпляра, которая является подклассом нового интерфейса Functionality. Это называется композицией: вместо наследования способности через наследование класс состоит из объектов с правильной способностью;
Ответ 4
Непосредственно из Шаблон стратегии Wikipedia article:
Шаблон стратегии полезен для ситуаций, когда необходимо динамически менять алгоритмы, используемые в приложении. Шаблон стратегии призван обеспечить средство определения семейства алгоритмов, инкапсулировать каждый в качестве объекта и сделать их взаимозаменяемыми. Шаблон стратегии позволяет алгоритмам независимо варьироваться от клиентов, которые их используют.
Ответ 5
Плотно связанный шаблон - это шаблон делегата; в обоих случаях часть работы передается другому компоненту. Если я правильно понимаю, разница между этими шаблонами такова (и, пожалуйста, поправьте меня, если я ошибаюсь):
-
В шаблоне Делегат делегат создается экземпляром класса (делегирования); это позволяет повторное использование кода по составу, а не наследованию. Окружающий класс может быть осведомлен о конкретном конкретном типе делегата, например. если он вызывает сам конструктор (в отличие от использования factory).
-
В шаблоне Стратегия компонент, выполняющий стратегию, является зависимостью, предоставляемой входящему (использующему) компоненту через его конструктор или сеттер (согласно вашей религии). Используемый компонент полностью не знает, какая стратегия используется; стратегия всегда вызывается через интерфейс.
Кто-нибудь знает какие-либо другие отличия?
Ответ 6
Чтобы добавить к уже великолепным ответам: шаблон стратегии имеет сильное сходство с передачей функции (или функций) другой функции. В стратегии это делается путем обертывания указанной функции в объект, за которым следует передача объекта. Некоторые языки могут передавать функции напрямую, поэтому они вообще не нуждаются в шаблоне. Но другие языки не могут передавать функции, но can передавать объекты; тогда применяется шаблон.
Особенно в Java-подобных языках вы обнаружите, что тип zoo языка довольно мал и что ваш единственный способ расширить его - создать объекты. Поэтому большинство решений проблем состоит в том, чтобы придумать шаблон; способ создания объектов для достижения конкретной цели. Языки с более богатыми зоопарками часто имеют более простые способы решения проблем, но более богатые типы также означают, что вам нужно больше времени изучать систему типов. Языки с динамической типизированной дисциплиной часто также подрывают проблему вокруг проблемы.