深圳幻海软件技术有限公司 欢迎您!

状态模式

2023-03-13

我们把影响对象行为的一个或多个动态变化的属性称为状态,状态模式所处理的对象是有状态的,当然状态复杂才能体现出模式的精髓。简单一点例子就是等红路灯namespace状态模式一{internalclassProgram{staticvoidMain(string[]args){TrafficLightt

我们把影响对象行为的一个或多个动态变化的属性称为状态,状态模式所处理的对象是有状态的,当然状态复杂才能体现出模式的精髓。

简单一点例子就是等红路灯

namespace 状态模式一
{
    internal class Program
    {
        static void Main(string[] args)
        {
            TrafficLight trafficLight = new TrafficLight(new GreenLightState());
            trafficLight.Show();
            trafficLight.SetState(new YellowLightState());
            trafficLight.Show();
            trafficLight.SetState(new RedLightState());
            trafficLight.Show();
        }
    }

    /// <summary>
    /// 定义状态的抽象类
    /// </summary>
    public abstract class TrafficLighState
    {
        public abstract void Display();
    }

    #region 具体实现
    public class RedLightState : TrafficLighState
    {
        public override void Display()
        {
            Console.WriteLine("RedLight");
        }
    }
    public class GreenLightState : TrafficLighState
    {
        public override void Display()
        {
            Console.WriteLine("GreenLight");
        }
    }
    public class YellowLightState : TrafficLighState
    {
        public override void Display()
        {
            Console.WriteLine("YellowLight");
        }
    } 
    #endregion

    /// <summary>
    /// 状态控制类
    /// </summary>
    public class TrafficLight
    {
        private TrafficLighState trafficLighState;
        public TrafficLight(TrafficLighState trafficLighState)
        {
            this.trafficLighState = trafficLighState;
        }
        public void SetState(TrafficLighState state)
        {
            trafficLighState = state;
        }
        public void Show()
        {
            trafficLighState.Display();
        }
    }
}

上面实例状态控制类控制的是一个状态的类型,看起来很眼熟,比如策略模式(他是通过委托来控制行为),又比如模板方法(通过继承来控制行为),只不过这里是控制一个状态类。

下面通过汽车的状态举的例子:

using System.Numerics;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace 状态模式二
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var lamborghini = new Car();

            Display(lamborghini.CurrentState);
            lamborghini.TaskAction(Action.Start);

            Display(lamborghini.CurrentState);
            lamborghini.TaskAction(Action.Start);

            Display(lamborghini.CurrentState);
            lamborghini.TaskAction(Action.Accelerate); //加速

            Display(lamborghini.CurrentState);
            lamborghini.TaskAction(Action.Stop);

            Display(lamborghini.CurrentState);
            /* result
                车辆当前状态: Stopped
                车辆当前状态:Started
                车辆当前状态:Started
                车辆当前状态:Running
                车辆当前状态:Stopped
            */
        }
        static void Display(State state)
        {
            Console.WriteLine($"车辆当前状态:{state}");
        }
    }
    /// <summary>
    /// 模拟汽车的状态和驾驶员的动作判断车辆当前的状态
    /// </summary>
    public class Car
    {
        private State state = State.Stopped;
        public State CurrentState { get { return state; } }

        public void TaskAction(Action action)
        {
            state = (state, action) switch
            {
                (State.Stopped, Action.Start) => State.Started,
                (State.Started, Action.Accelerate) => State.Running,
                (State.Started, Action.Stop) => State.Stopped,
                (State.Running, Action.Stop) => State.Stopped,
                _ => state
            };
        }
    }
    public enum State { Stopped, Started, Running }
    public enum Action { Stop, Start, Accelerate }
}