状态模式

文章目录

1.UML类图

2.状态基类

csharp 复制代码
public abstract class State 
{
    public string? Name { get; set; }
    public StateMachine? StateMachine {get; set;}
    public abstract void Exit();
    public abstract void Enter();
}

3.状态实现类

  1. StateA
csharp 复制代码
public class StateA : State 
{
    public StateA(string name) 
    {
        Name = name;
    }

    public override void Enter()
    {
        Console.WriteLine("进入状态A,Name:{0}", Name);
    }

    public override void Exit()
    {
        Console.WriteLine("退出状态A,Name:{0}", Name);
    }
}
  1. StateB
csharp 复制代码
public class StateB : State 
{
    public StateB(string name) 
    {
        Name = name;
    }

    public override void Enter()
    {
        Console.WriteLine("进入状态B,Name:{0}", Name);
    }

    public override void Exit()
    {
        Console.WriteLine("退出状态B,Name:{0}", Name);
    }  
}
  1. StateC
csharp 复制代码
public class StateC : State 
{
    public StateC(string name) 
    {
        Name = name;
    }

    public override void Enter()
    {
        Console.WriteLine("进入状态C,Name:{0}", Name);
    }

    public override void Exit()
    {
        Console.WriteLine("退出状态C,Name:{0}", Name);
    }  
}

3.状态机管理类

csharp 复制代码
public class StateMachine 
{
    public string? Name {get; set;}  
    private List<State> states = new List<State>();
    private State? CurrentState;

    public StateMachine(string name) 
    {
        Name = name;
    }
    

    public void AddState(State state) 
    {
        if (!states.Contains(state))
        {
            states.Add(state);
            state.StateMachine = this;
        }
    }

    public void RemoveState(State state) 
    {
        if (states.IndexOf(state) == -1)
            return;
        state.Exit();
        CurrentState = null;
        states.Remove(state);
    }

    public void ChangeState(State state) 
    {
        CurrentState?.Exit();
        CurrentState = state;
        CurrentState.Enter();
    }

    public void Switch2NextState() 
    {
        if (CurrentState != null)
        {
            int index = states.IndexOf(CurrentState);
            // 排除状态不存在和最后一个状态的情况    
            if (index == -1)
                return;
            if (index + 1 >= states.Count)
                return;
            CurrentState.Exit();
            CurrentState = states[index + 1]; 
        }
        else    // 当前状态为空 则直接进入列表中的第一个状态
        {
            CurrentState = states[0];
        }
        CurrentState.Enter();
    }

    public void Switch2PreviousState() 
    {
        if (CurrentState != null)
        {
            int index = states.IndexOf(CurrentState);
            // 排除状态不存在和第一个状态的情况    
            if (index == -1)
                return;
            if (index == 0)
                return;
            CurrentState.Exit();
            CurrentState = states[index - 1]; 
        }
        else    // 当前状态为空 则直接进入列表中的最后一个状态
        {
            CurrentState = states[states.Count - 1];
        }
        CurrentState.Enter();
    }
}  

使用示例

csharp 复制代码
StateMachine stateMachine = new StateMachine("状态模式测试");
stateMachine.AddState(new StateA("状态A"));
StateB stateB = new StateB("状态B");
stateMachine.AddState(stateB);
stateMachine.AddState(new StateC("状态C"));

stateMachine.Switch2NextState();
stateMachine.Switch2NextState();
stateMachine.Switch2NextState();
stateMachine.Switch2PreviousState();
stateMachine.Switch2PreviousState();
stateMachine.ChangeState(stateB);

/*
进入状态A,Name:状态A
退出状态A,Name:状态A
进入状态B,Name:状态B
退出状态B,Name:状态B
进入状态C,Name:状态C
退出状态C,Name:状态C
进入状态B,Name:状态B
退出状态B,Name:状态B
进入状态A,Name:状态A
退出状态A,Name:状态A
进入状态B,Name:状态B
*/
相关推荐
阿蒙Amon28 分钟前
C#每日面试题-常量和只读变量的区别
java·面试·c#
我是唐青枫33 分钟前
C#.NET ConcurrentBag<T> 设计原理与使用场景
c#·.net
大王小生1 小时前
C# CancellationToken
开发语言·c#·token·cancellation
listhi5201 小时前
基于C#实现屏幕放大镜功能
开发语言·c#
魅影骑士00103 小时前
柯里化函数
后端·设计模式
该用户已不存在4 小时前
不止是初始化,4个C# 构造函数解析与实例
后端·c#·.net
无风听海7 小时前
深入讲解 C# 中 string 如何支持 CultureInfo
开发语言·c#
BHXDML7 小时前
Java 设计模式详解
java·开发语言·设计模式
wzfj123457 小时前
FreeRTOS xTaskCreateStatic 详解
开发语言·c#
kylezhao20198 小时前
C# DataGridView 控件使用详解
c#