C# 实现状态模式:构建简易状态机

19 阅读3分钟

前言

在游戏开发、UI 控制、流程管理等场景中,对象的行为往往依赖于其所处的"状态"。直接使用大量 if-elseswitch 判断状态不仅代码冗余,而且难以维护和扩展。状态模式(State Pattern) 正是为解决这类问题而生——它将每个状态封装成独立的类,使状态切换逻辑清晰、结构灵活。

本文将通过一个简洁的 C# 示例,演示如何利用接口与类实现状态模式,并开发一个基础的状态机(State Machine),帮助大家快速掌握这一经典设计模式的核心思想。

状态模式的基本结构

状态模式的关键在于:

定义一个统一的状态接口(Istate),声明进入、退出和更新等通用行为;

每个具体状态(如 stateAstateB)实现该接口,封装自身逻辑;

由一个状态机类(stateMachine)负责管理当前状态,并在切换时自动调用 exit()enter() 方法,确保状态转换的完整性。

这种设计使得新增状态无需修改现有代码,符合"开闭原则"。

代码实现

以下是完整的 C# 实现代码,包含状态接口、两个具体状态类、状态机以及测试入口:

namespace state
{
    /// <summary>
    /// 定义状态接口
    /// </summary>
    public interface Istate
    {
        public void enter();
        public void exit();
        public void update();
    }
    /// <summary>
    /// 通过接口实现状态A类
    /// </summary>
    public class stateA : Istate
    {
        public void enter()
        {
            Console.WriteLine("进入A状态");
        }
        public void exit()
        {
            Console.WriteLine("退出A状态");
        }
        public void update()
        {
            Console.WriteLine("更新A状态");

        }
        /// <summary>
        /// 通过接口实现状态B类
        /// </summary>
        public class stateB : Istate
        {
            public void enter()
            {
                Console.WriteLine("进入B状态");
            }
            public void exit()
            {
                Console.WriteLine("退出B状态");
            }
            public void update()
            {
                Console.WriteLine("更新B状态");

            }
            /// <summary>
            /// 状态切换类(状态机类)
            /// 先退出当前状态,再进入下一状态然后更新
            /// </summary>
            class stateMachine
            {
                private Istate _currentState;
                public void setState(Istate currentState)
                {
                    if (_currentState != null)
                    {
                        _currentState.exit();
                    }
                    _currentState = currentState;
                    _currentState.enter();
                }
                public void update()
                {
                    _currentState.update();
                }

            }

            internal class Program
            {
                static void Main(string[] args)
                {
                    stateMachine sm = new stateMachine();
                    sm.setState(new stateA());
                    sm.update();
                    sm.setState(new stateB());
                    sm.update();

                }

            }
        }
    }
}

注意:上述代码中 stateB 被错误地嵌套在 stateA 类内部。虽然语法上合法(C# 支持嵌套类),但不符合常规设计习惯。建议将 stateAstateB 作为同级类定义,以提高可读性和可维护性。

运行结果

程序执行后,控制台输出如下:

从输出可见:

1、首先设置状态为 stateA,触发"进入A状态";

2、调用 update() 输出"更新A状态";

3、切换到 stateB,先退出 A("退出A状态"),再进入 B("进入B状态");

4、最后更新 B 状态("更新B状态")。

整个流程清晰体现了状态机的切换机制。

总结

通过本例,我们实现了基于接口的状态模式,并构建了一个轻量级状态机。该模式有效解耦了状态逻辑与主控逻辑,使系统更易于扩展和测试。例如,在游戏中,角色可能有"站立"、"奔跑"、"攻击"等状态,每种状态下的输入响应和动画播放都不同——使用状态模式即可优雅处理。

尽管示例代码存在类嵌套的问题,但其核心思想完全正确。在实际项目中,建议将各状态类独立定义,并结合依赖注入或工厂模式进一步优化架构。

关键词

状态模式、状态机、C#、设计模式、Istate、stateMachine、面向对象、代码解耦

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。

也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

优秀是一种习惯,欢迎大家留言学习!

出处:mp.weixin.qq.com/s/kMm8faTJmoVDYu5AErb0kw

声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!