‌状态模式(State Pattern)

‌状态模式(State Pattern)

定义

‌状态模式(State Pattern)‌ 是一种行为设计模式,允许对象在其 ‌内部状态改变时改变它的行为‌,使对象看起来像是修改了自身的类。该模式通过将状态相关的行为封装到独立的类中,消除复杂的条件判断逻辑,提升代码可维护性。

核心思想

  • 状态与行为绑定‌:将每个状态的行为封装到独立类中,避免 if-else 或 switch-case 的泛滥。

  • 动态切换状态‌:对象通过委托调用当前状态类的方法,状态变更时自动切换行为逻辑。

  • 开闭原则‌:新增状态时无需修改现有代码,只需添加新的状态类。

模式结构

角色 职责
Context 上下文类,持有当前状态对象,定义客户端交互接口。
IState 状态接口,声明状态相关的操作方法(如 Handle())。
ConcreteState 具体状态类,实现 IState 接口,定义该状态下的具体行为逻辑。

主要解决的问题

  • 消除复杂条件分支‌:将状态相关的逻辑分散到独立的类中,避免代码臃肿。

  • 状态转换透明化‌:通过状态对象管理状态迁移逻辑,使代码更清晰易维护。

  • 支持动态扩展‌:新增状态时无需修改现有状态类和上下文类。

代码示例

场景描述

模拟电梯(Elevator)的状态切换:

  • 电梯有 ‌开门(Open)‌、‌关门(Close)‌、‌运行(Run)‌、‌停止(Stop)‌ 四种状态。
  • 不同状态下,电梯对同一操作(如按下按钮)的响应不同。

实现代码

using System;

// 状态接口
interface IElevatorState
{
    void Handle(Elevator elevator);
}

// 具体状态:开门状态
class OpenState : IElevatorState
{
    public void Handle(Elevator elevator)
    {
        Console.WriteLine("电梯门已打开,无法移动。");
        // 切换到关门状态
        elevator.SetState(new CloseState());
    }
}

// 具体状态:关门状态
class CloseState : IElevatorState
{
    public void Handle(Elevator elevator)
    {
        Console.WriteLine("电梯门已关闭,准备运行。");
        // 切换到运行状态
        elevator.SetState(new RunState());
    }
}

// 具体状态:运行状态
class RunState : IElevatorState
{
    public void Handle(Elevator elevator)
    {
        Console.WriteLine("电梯正在运行,即将到达目标楼层。");
        // 切换到停止状态
        elevator.SetState(new StopState());
    }
}

// 具体状态:停止状态
class StopState : IElevatorState
{
    public void Handle(Elevator elevator)
    {
        Console.WriteLine("电梯已停止,准备开门。");
        // 切换到开门状态
        elevator.SetState(new OpenState());
    }
}

// 上下文类:电梯
class Elevator
{
    private IElevatorState _currentState;

    public Elevator()
    {
        // 初始状态为停止状态
        _currentState = new StopState();
    }

    // 设置当前状态
    public void SetState(IElevatorState state)
    {
        _currentState = state;
    }

    // 触发状态行为(例如用户按下按钮)
    public void PressButton()
    {
        _currentState.Handle(this);
    }
}

// 客户端调用
class Program
{
    static void Main()
    {
        Elevator elevator = new Elevator();

        // 模拟用户多次按下按钮
        elevator.PressButton(); // 停止 → 开门
        elevator.PressButton(); // 开门 → 关门
        elevator.PressButton(); // 关门 → 运行
        elevator.PressButton(); // 运行 → 停止
    }
}

输出结果

电梯已停止,准备开门。  
电梯门已打开,无法移动。  
电梯门已关闭,准备运行。  
电梯正在运行,即将到达目标楼层。  

总结

优点‌

  • 代码清晰‌:状态逻辑分散到独立类中,避免条件分支嵌套。

  • 高扩展性‌:新增状态只需添加新类,无需修改现有代码。

  • 封装状态迁移‌:状态切换逻辑由具体状态类自行管理,上下文类无需关心细节。

缺点

  • 类数量膨胀‌:状态较多时会导致类的数量增加。

  • 状态迁移复杂度‌:若状态转换逻辑复杂,可能需要额外的协调机制。

posted @ 2025-04-24 16:02  刘继先  阅读(27)  评论(0)    收藏  举报