状态模式 (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. 状态数据分离
    • 将状态行为与具体状态数据分离,适用于复杂业务逻辑。

小结

  • 状态模式将状态与行为解耦,避免了复杂的条件逻辑。
  • 适用于对象行为随状态变化的场景。
  • 实现上要平衡状态类数量与复杂性的关系,防止类爆炸。
相关推荐
lyh13442 天前
【Fiddler工具判断前后端Bug】
状态模式
季鸢2 天前
Java设计模式之状态模式详解
java·设计模式·状态模式
萌新小码农‍3 天前
Spring框架学习day7--SpringWeb学习(概念与搭建配置)
学习·spring·状态模式
EndingCoder4 天前
React从基础入门到高级实战:React 高级主题 - React 微前端实践:构建可扩展的大型应用
前端·javascript·react.js·前端框架·状态模式
何双新7 天前
第14讲、Odoo 18 实现一个Markdown Widget模块
python·状态模式
zwjapple8 天前
react-native的token认证流程
react native·状态模式·token
何中应9 天前
【设计模式-4.6】行为型——状态模式
java·设计模式·状态模式
失败尽是常态Z10 天前
基于JWT+Redis的登录流程实现
java·数据库·redis·状态模式·jwt·用户登录
暴躁哥12 天前
深入理解设计模式之状态模式
设计模式·状态模式
熙客13 天前
行为型:状态模式
状态模式