C#设计模式--状态模式(State Pattern)

状态模式 是一种行为设计模式,它允许对象在其内部状态发生变化时改变其行为。这种模式的核心思想是将状态封装在独立的对象中,而不是将状态逻辑散布在整个程序中。

用途

  1. 简化复杂的条件逻辑:通过将不同的状态封装在不同的类中,可以避免大量的条件语句,使代码更清晰、更易于维护。
  2. 提高可扩展性:添加新的状态或修改现有状态的行为时,只需修改或新增相应的状态类,而不需要修改现有的代码。
  3. 提高代码的复用性:状态对象可以在多个上下文对象之间共享,提高代码的复用性。
    示例代码及类图

示例1:交通信号灯

csharp 复制代码
public interface ILightState
{
    void Handle(TrafficLight context);
}

public class RedLightState : ILightState
{
    public void Handle(TrafficLight context)
    {
        Console.WriteLine("Red Light");
        context.SetState(new GreenLightState());
    }
}

public class GreenLightState : ILightState
{
    public void Handle(TrafficLight context)
    {
        Console.WriteLine("Green Light");
        context.SetState(new YellowLightState());
    }
}

public class YellowLightState : ILightState
{
    public void Handle(TrafficLight context)
    {
        Console.WriteLine("Yellow Light");
        context.SetState(new RedLightState());
    }
}

public class TrafficLight
{
    private ILightState _state;

    public TrafficLight(ILightState initialState)
    {
        _state = initialState;
    }

    public void ChangeLight()
    {
        _state.Handle(this);
    }

    public void SetState(ILightState state)
    {
        _state = state;
    }
}

类图

ILightState +void Handle(TrafficLight context) RedLightState +void Handle(TrafficLight context) GreenLightState +void Handle(TrafficLight context) YellowLightState +void Handle(TrafficLight context) TrafficLight -ILightState _state +TrafficLight(ILightState initialState) +void ChangeLight() +void SetState(ILightState state)

示例2:订单状态管理

csharp 复制代码
public interface IOrderState
{
    void Handle(Order context);
}

public class PendingState : IOrderState
{
    public void Handle(Order context)
    {
        Console.WriteLine("Order is pending");
        context.SetState(new ProcessingState());
    }
}

public class ProcessingState : IOrderState
{
    public void Handle(Order context)
    {
        Console.WriteLine("Order is being processed");
        context.SetState(new ShippedState());
    }
}

public class ShippedState : IOrderState
{
    public void Handle(Order context)
    {
        Console.WriteLine("Order has been shipped");
        context.SetState(new DeliveredState());
    }
}

public class DeliveredState : IOrderState
{
    public void Handle(Order context)
    {
        Console.WriteLine("Order has been delivered");
    }
}

public class Order
{
    private IOrderState _state;

    public Order(IOrderState initialState)
    {
        _state = initialState;
    }

    public void Process()
    {
        _state.Handle(this);
    }

    public void SetState(IOrderState state)
    {
        _state = state;
    }
}

类图

IOrderState +void Handle(Order context) PendingState +void Handle(Order context) ProcessingState +void Handle(Order context) ShippedState +void Handle(Order context) DeliveredState +void Handle(Order context) Order -IOrderState _state +Order(IOrderState initialState) +void Process() +void SetState(IOrderState state)

示例3:游戏角色状态

csharp 复制代码
public interface ICharacterState
{
    void Handle(Character context);
}

public class IdleState : ICharacterState
{
    public void Handle(Character context)
    {
        Console.WriteLine("Character is idle");
        context.SetState(new WalkingState());
    }
}

public class WalkingState : ICharacterState
{
    public void Handle(Character context)
    {
        Console.WriteLine("Character is walking");
        context.SetState(new RunningState());
    }
}

public class RunningState : ICharacterState
{
    public void Handle(Character context)
    {
        Console.WriteLine("Character is running");
        context.SetState(new IdleState());
    }
}

public class Character
{
    private ICharacterState _state;

    public Character(ICharacterState initialState)
    {
        _state = initialState;
    }

    public void Move()
    {
        _state.Handle(this);
    }

    public void SetState(ICharacterState state)
    {
        _state = state;
    }
}

类图

ICharacterState +void Handle(Character context) IdleState +void Handle(Character context) WalkingState +void Handle(Character context) RunningState +void Handle(Character context) Character -ICharacterState _state +Character(ICharacterState initialState) +void Move() +void SetState(ICharacterState state)

代码解析

  1. 状态接口 (IState):定义了一个 Handle 方法,所有具体状态类都需要实现这个方法。
  2. 具体状态 (StateAStateB):实现了 IState 接口,具体实现了 Handle 方法。在处理完当前状态后,可以改变上下文的当前状态。
  3. 上下文类 (Context):维护一个对当前状态的引用,并提供一个方法 Request 来调用当前状态的 Handle 方法。上下文还提供了一个属性 State 来改变当前状态,并在状态改变时输出相关信息。

优点

  1. 简化条件逻辑:通过将状态逻辑封装在不同的类中,减少了大量的条件语句,使代码更清晰、更易于维护。
  2. 提高可扩展性:添加新的状态或修改现有状态的行为时,只需修改或新增相应的状态类,而不需要修改现有的代码。
  3. 提高代码的复用性:状态对象可以在多个上下文对象之间共享,提高代码的复用性。

缺点

  1. 增加类的数量:每种状态都需要一个类,这可能会导致类的数量增多,增加系统的复杂性。
  2. 状态转换逻辑分散:状态转换的逻辑分布在不同的状态类中,有时可能难以追踪和理解。
  3. 过度设计:对于简单的状态转换,使用状态模式可能会显得过于复杂,增加不必要的开销。

总结

状态模式适用于需要管理多种状态和状态转换的场景,特别是在状态逻辑较为复杂的情况下。通过将状态逻辑封装在独立的类中,可以使代码更加模块化、易于维护和扩展。然而,在简单的情况下,使用状态模式可能会增加不必要的复杂性。

相关推荐
星栈独行7 小时前
翻完 Pi 源码:它和 Codex、Claude Code 有何不同
开发语言·javascript·人工智能·程序人生
qq_448011168 小时前
C语言中的变量和函数的定义与声明
android·c语言·开发语言
孫治AllenSun9 小时前
【DataX】生产环境搭建DataX集群案例
java·开发语言·jvm
c2385610 小时前
把 C++ 内存分配拆透:new 与 malloc 的三层血缘
开发语言·c++·算法
moonsims11 小时前
星闪在跨域无人化系统作用
开发语言·php
Iruoyaoxh11 小时前
栈和队列~
java·开发语言
Hrain-AI12 小时前
2026 企业 AI 编程智能体实战:Codex 与 Claude Code
开发语言·人工智能·kotlin
wdfk_prog12 小时前
嵌入式面试真题第 13 题:单硬件 Timer 下的高精度多路软件定时器架构设计
c语言·开发语言·面试·职场和发展·嵌入式
oort12312 小时前
吃上了自家的细糠,还挺丝滑,用起来手感还行,OortCloud发布新版AI编程平台,下载 OortCodex,Token多,免费薅
大数据·开发语言·人工智能·ai编程
slandarer12 小时前
MATLAB | 泰勒图绘制,支持各种角度范围
开发语言·数学建模·matlab·nature·顶刊·泰勒图