🎉 Ура! Після трьох років роботи, я нарешті випустив англійську версію книжки про патерни! Ось вона »

C#: Стан

State Стан State

Стан — це поведінковий патерн, що дозволяє динамічно змінювати поведінку об’єкта при зміні його стану.

Поведінки, які залежать від стану, переїзджають в окремі класи. Початковий клас зберігає посилання на один з таких об’єктів-станів та делегує йому роботу.

Детальніше про Стан

Особливості паттерна на C#

Складність:

Популярність:

Застосування: Патерн Стан часто використовують в C# для перетворення в об’єкти величезних стейт-машин, побудованих на операторах switch.

Ознаки застосування патерну: Методи класу делегують роботу одному вкладеному об’єктові.

Приклад: Структура патерну

Цей приклад показує структуру патерну Стан, а саме — з яких класів він складається, які ролі ці класи виконують і як вони взаємодіють один з одним.

Program.cs: Приклад структури патерну

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RefactoringGuru.DesignPatterns.State.Structural
{
    class Context
    {
        private State _state = null;

        public Context(State state)
        {
            this.transitionTo(state);
        }

        public void transitionTo(State state)
        {
            Console.Write("Context: Transition to " + state.ToString() + ".\n");
            this._state = state;
            this._state.setContext(this);
        }

        public void request1()
        {
            this._state.handle1();
        }

        public void request2()
        {
            this._state.handle2();
        }
    }
    
    abstract class State
    {
        protected Context context;

        public void setContext(Context context)
        {
            this.context = context;
        }

        public abstract void handle1();

        public abstract void handle2();
    }

    class ConcreteStateA : State
    {
        public override void handle1()
        {
            Console.Write("ConcreteStateA handles request1.\n");
            Console.Write("ConcreteStateA wants to change the state of the context.\n");
            this.context.transitionTo(new ConcreteStateB());
        }

        public override void handle2()
        {
            Console.Write("ConcreteStateA handles request2.\n");
        }
    }

    class ConcreteStateB : State
    {
        public override void handle1()
        {
            Console.Write("ConcreteStateB handles request1.\n");
        }

        public override void handle2()
        {
            Console.Write("ConcreteStateB handles request2.\n");
            Console.Write("ConcreteStateB wants to change the state of the context.\n");
            this.context.transitionTo(new ConcreteStateA());
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Client.ClientCode();
        }
    }

    class Client
    {
        public static void ClientCode()
        {
            var context = new Context(new ConcreteStateA());
            context.request1();
            context.request2();
        }
    }
}

Output.txt: Результат виконання

Context: Transition to RefactoringGuru.DesignPatterns.State.Structural.ConcreteStateA.
ConcreteStateA handles request1.
ConcreteStateA wants to change the state of the context.
Context: Transition to RefactoringGuru.DesignPatterns.State.Structural.ConcreteStateB.
ConcreteStateB handles request2.
ConcreteStateB wants to change the state of the context.
Context: Transition to RefactoringGuru.DesignPatterns.State.Structural.ConcreteStateA.