状态模式 (State Pattern)

文章目录

状态模式 (State Pattern)

状态模式 是一种 行为型设计模式,允许对象在其内部状态改变时改变其行为,使得对象看起来像是改变了其类。


原理

  1. 核心思想
    • 将与对象状态相关的行为抽象到独立的状态类中。
    • 通过在不同状态下切换状态类,改变对象的行为。
  2. 适用场景
    • 对象的行为随状态的改变而改变。
    • 状态的条件逻辑复杂,使用模式可以避免复杂的 if-elseswitch-case
  3. 参与角色
    • Context(上下文类)
      • 管理状态,并向客户端提供统一的接口。
      • 内部维护一个当前状态实例。
    • State(状态接口)
      • 定义具体状态的行为接口。
    • ConcreteState(具体状态类)
      • 实现状态接口,定义特定状态的行为。

优点

  1. 消除条件逻辑
    • 通过多态分离状态行为,避免复杂的条件判断语句。
  2. 增加扩展性
    • 增加新状态无需修改已有代码,符合 开闭原则
  3. 状态自包含
    • 每个状态独立,易于管理。

缺点

  1. 增加类数量
    • 每种状态都需要一个类,导致类的数量增加。
  2. 状态切换复杂性
    • 如果状态间切换规则复杂,可能使上下文类难以管理。

示例代码

场景描述

模拟一个订单系统,订单可以处于不同状态(新建、支付、发货、完成)。不同状态下的行为有所不同。


1. 定义状态接口
java 复制代码
// 状态接口
public interface OrderState {
    void handle(OrderContext context);
}

2. 定义具体状态类
java 复制代码
// 新建状态
public class NewState implements OrderState {
    @Override
    public void handle(OrderContext context) {
        System.out.println("Order is in 'New' state.");
        context.setState(new PaidState());
    }
}

// 支付状态
public class PaidState implements OrderState {
    @Override
    public void handle(OrderContext context) {
        System.out.println("Order is in 'Paid' state.");
        context.setState(new ShippedState());
    }
}

// 发货状态
public class ShippedState implements OrderState {
    @Override
    public void handle(OrderContext context) {
        System.out.println("Order is in 'Shipped' state.");
        context.setState(new CompletedState());
    }
}

// 完成状态
public class CompletedState implements OrderState {
    @Override
    public void handle(OrderContext context) {
        System.out.println("Order is in 'Completed' state.");
        // 最终状态,无法再改变
    }
}

3. 定义上下文类
java 复制代码
// 上下文类
public class OrderContext {
    private OrderState state;

    public OrderContext() {
        // 初始状态为新建
        this.state = new NewState();
    }

    public void setState(OrderState state) {
        this.state = state;
    }

    public void processOrder() {
        state.handle(this);
    }
}

4. 客户端代码
java 复制代码
public class StatePatternExample {
    public static void main(String[] args) {
        OrderContext order = new OrderContext();

        // 流程处理
        order.processOrder(); // 新建 -> 支付
        order.processOrder(); // 支付 -> 发货
        order.processOrder(); // 发货 -> 完成
        order.processOrder(); // 完成状态,无进一步操作
    }
}

输出结果
text 复制代码
Order is in 'New' state.
Order is in 'Paid' state.
Order is in 'Shipped' state.
Order is in 'Completed' state.

UML 类图

复制代码
        +-----------------+
        |    OrderState   |
        +-----------------+
        | + handle(Context)|
        +-----------------+
               ^
               |
        +------+-------+--------------------+-------------------+
        |              |                    |                   |
  +-------------+ +-------------+    +-------------+     +-------------+
  |  NewState   | |  PaidState  |    | ShippedState|     |CompletedState|
  +-------------+ +-------------+    +-------------+     +-------------+
  | + handle()  | | + handle()  |    | + handle()  |     | + handle()  |
  +-------------+ +-------------+    +-------------+     +-------------+
               ^
               |
        +----------------------+
        |     OrderContext     |
        +----------------------+
        | - state : OrderState |
        | + setState(state)    |
        | + processOrder()     |
        +----------------------+

使用场景

  1. 状态转换系统
    • 订单、流程审批等具有状态转换逻辑的系统。
  2. 游戏开发
    • 玩家角色的状态切换(如站立、行走、跳跃等)。
  3. 工作流引擎
    • 工单的状态流转(如创建、处理中、已完成)。

扩展与优化

  1. 状态复用
    • 如果某些状态是无状态的,可以用单例模式实现。
  2. 状态机框架
    • 对于复杂状态切换,可以使用现成的状态机框架(如 Spring Statemachine)。
  3. 状态数据分离
    • 将状态行为与具体状态数据分离,适用于复杂业务逻辑。

小结

  • 状态模式将状态与行为解耦,避免了复杂的条件逻辑。
  • 适用于对象行为随状态变化的场景。
  • 实现上要平衡状态类数量与复杂性的关系,防止类爆炸。
相关推荐
前端不太难2 小时前
HarmonyOS App 工程深水区:从能跑到可控
华为·状态模式·harmonyos
前端不太难17 小时前
HarmonyOS 游戏上线前必做的 7 类极端场景测试
游戏·状态模式·harmonyos
光影少年20 小时前
AI 前端 / 高级前端
前端·人工智能·状态模式
智商偏低20 小时前
PostGIS+GeoServer+OpenLayers 数据加载无显示问题排查及自定义坐标系配置文档
状态模式
小王不爱笑13221 小时前
序列化和反序列化
状态模式
程序员Sunday1 天前
说点不一样的。GPT-5.3 与 Claude Opus 4.6 同时炸场,前端变天了?
前端·gpt·状态模式
前端不太难1 天前
HarmonyOS 游戏项目,从 Demo 到可上线要跨过哪些坑
游戏·状态模式·harmonyos
万物得其道者成1 天前
阿里云 H5 一键登录接入实战:前后端完整实现
阿里云·云计算·状态模式
前端不太难1 天前
在 HarmonyOS 上,游戏状态该怎么“死而复生”
游戏·状态模式·harmonyos
木斯佳2 天前
前端八股文面经大全:26届秋招滴滴校招前端一面面经-事件循环题解析
前端·状态模式