状态模式

文章目录

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
*/
相关推荐
小马不起床3 小时前
零基础玩转 FastAPI_11:前端后台管理页面
前端·状态模式·fastapi
曹牧7 小时前
C#:输入的字符串格式不正确
c#
博风8 小时前
8、设计模式应用举例:适配器模式:Iterator接口与Enumeration接口
设计模式·适配器模式
高晶10 小时前
ARM 嵌入式 Linux 系统 U-Boot 开发与移植实战M
设计模式·程序员
shmily麻瓜小菜鸡10 小时前
前端实现图片与PDF文字识别敏感信息打码方案
前端·pdf·状态模式
根号五12 小时前
JetBrains Rider 使用教程(1)新建解决方案
c#·jetbrains rider
青企通12 小时前
APP 开发成本估算:从需求到上架的完整拆解与工作量模型
产品运营·状态模式
for_ever_love__12 小时前
LangGraph State 设计:多节点之间怎么安全地共享数据
redis·mysql·状态模式·checkpoint·state·状态图·langgraph
海天鹰13 小时前
C#:接收从打开方式打开的参数
c#
宝桥南山13 小时前
.NET 11 - 尝试一下Minimal API中的异步验证新特性
microsoft·微软·c#·asp.net·.net·.netcore