状态模式 (State Pattern)

文章目录

状态模式 (State Pattern)

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


原理

  1. 核心思想 :
    • 将与对象状态相关的行为抽象到独立的状态类中。
    • 通过在不同状态下切换状态类,改变对象的行为。
  2. 适用场景 :
    • 对象的行为随状态的改变而改变。
    • 状态的条件逻辑复杂,使用模式可以避免复杂的 if-else 或 switch-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. 状态数据分离 :
    • 将状态行为与具体状态数据分离,适用于复杂业务逻辑。

小结

  • 状态模式将状态与行为解耦,避免了复杂的条件逻辑。
  • 适用于对象行为随状态变化的场景。
  • 实现上要平衡状态类数量与复杂性的关系,防止类爆炸。
相关推荐
m0_敲代码的彭于晏1681 天前
Vercel 前端部署与全栈开发实战指南
前端·状态模式
星恒随风1 天前
Linux线程同步与互斥(二):从日志系统与线程池设计,到线程安全单例、可重入函数和死锁原理
linux·运维·状态模式
学Linux的语莫2 天前
python中类的常见写法
开发语言·python·状态模式
223糖2 天前
Tool Calling 是什么?用后端接口的思路讲清楚
状态模式
染指11104 天前
151.Agent-LangGraph-Send发送(Map-Reduce模式)
人工智能·python·langchain·状态模式·agents
鸽鸽程序猿5 天前
【项目】【在线判题系统】竞赛发布与撤销发布
状态模式
lemon_sjdk6 天前
从一段真实的 Electron IM 前端代码,看高级前端的工程化修养
前端·electron·状态模式·im
Nebula_g6 天前
云禾外卖补充—项目整体后端运行逻辑-对流程的更深层次理解
java·开发语言·网络·数据库·状态模式·javase
Wang's Blog6 天前
Java 项目实战: 交友项目:登录链路回顾与今日任务地图
java·开发语言·状态模式·交友
Java后端的Ai之路6 天前
14、ReactJS - 路由(Router)
前端·react.js·状态模式