Шаблон состояния

Как говорит Википедия:

Шаблон состояния — это поведенческий шаблон проектирования программного обеспечения, который позволяет объекту изменять свое поведение при изменении его внутреннего состояния. Этот паттерн близок к понятию конечные автоматы.

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

Теперь, когда мы получили определение шаблона состояния, мы приблизились к реальному примеру использования шаблона состояния. Давайте поговорим о руле в игрушечном автомобиле. Рулевое колесо можно заменить. Мы можем установить больший или меньший руль. Это не правило, однако, будем считать, что маленький руль создает больший угол наклона передних колес автомобиля, чем больший руль.

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

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

public interface ISteeringWheel
{
    void TurnLeft();
    void Straight();
    void TurnRight();
}

public class BigSteeringWheel : ISteeringWheel
{
    public void Straight()
    {
      Console.WriteLine("BigSteeringWheel is straight");
    }
 
    public void TurnLeft()
    {
        Console.WriteLine("BigSteeringWheel is turned left 10  
            degrees");
    }

    public void TurnRight()
    {
        Console.WriteLine("BigSteeringWheel is turned right 10  
            degrees");
    }
}
public class SmallSteeringWheel : ISteeringWheel
{
    public void Straight()
    {
        Console.WriteLine("SmallHandleBar is straight");
    }

    public void TurnLeft()
    {
        Console.WriteLine("SmallHandleBar is turned left 
           20 degrees");
    }
    public void TurnRight()
    {
        Console.WriteLine("SmallHandleBar is turned right 20  
            degrees");
    }
}
public class ToyAutomobile
{
    public ISteeringWheel SteeringWheel { get; private set; }
    public ToyAutomobile()
    {
        SteeringWheel = new BigSteeringWheel();
    }
    public void TurnLeft()
    {
         SteeringWheel.TurnLeft();
    }
    
    public void TurnRight()
    {
        SteeringWheel.TurnRight();
    }

    public void SetSteeringWheel(ISteeringWheel handleBar)
    {
        SteeringWheel = handleBar;
     }
}

Шаблон стратегии

Определение из Википедии:

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

Обратите внимание на такие слова, как «семейство используемых алгоритмов». Итак, давайте представим, что у нас есть настоящий автомобиль, и когда водитель поворачивает руль влево, мы хотим, чтобы наш автомобиль выполнял следующие действия:

- повернуть колеса автомобиля влево на 10 градусов

- включить левый оранжевый сигнал автомобиля

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

Давайте закодируем этот пример:

public interface ISteeringWheel
{
    void TurnLeft();
    void Straight();
    void TurnRight();
}
public class BigSteeringWheel : ISteeringWheel
{
    public void Straight()
    {
        Console.WriteLine("BigSteeringWheel is straight");
    }
 
    public void TurnLeft()
    {
        Console.WriteLine("BigSteeringWheel is turned left 
           10 degrees");
    }
    public void TurnRight()
    {
        Console.WriteLine("BigSteeringWheel is turned right 
            10 degrees");
    }
}
public interface ITurnSignal
{
    void TurnOnLeft();
    void TurnOnRight();
}
public class OrangeTurnSignal : ITurnSignal
{
    public void TurnOnLeft()
    {
        Console.WriteLine("Left OrangeTurnSignal is turned on");
    }
    public void TurnOnRight()
    {
        Console.WriteLine("Right OrangeTurnSignal is turned on");
    }
}
public class Automobile
{
    public ISteeringWheel SteeringWheel { get; private set; }
    public ITurnSignal TurnSignal { get; private set; }

    public Automobile()
    {
        SteeringWheel = new BigSteeringWheel();
        TurnSignal = new OrangeTurnSignal();
    }
    public void TurnLeft()
    {
        SteeringWheel.TurnLeft();
        TurnSignal.TurnOnLeft();
    }

    public void TurnRight()
    {
        SteeringWheel.TurnRight();
        TurnSignal.TurnOnRight();
    }
}

СУММЫ

Шаблон State и шаблон Strategy очень похожи друг на друга. Однако есть небольшая разница в том, что паттерн State имеет одно состояние, а все действия, такие как «Поверни налево» и «Поверни направо», инкапсулированы в один класс. С другой стороны, паттерн Стратегия не имеет одного состояния, а имеет много состояний, таких как «Штурвал» и «Сигнал поворота». Эти различные варианты поведения инкапсулированы с помощью различных объектов стратегии, таких как объекты «Штурвал» и «Сигнал поворота». Следовательно, это основное различие между шаблонами State и Strategy.

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

Паттерн состояния также можно рассматривать как альтернативу замене многих операторов «если — иначе» в классе.