【设计模式】行为型-状态模式

文章目录

  • 前言
  • 一、概念
  • 二、核心结构
  • [三、Java 代码实现(订单状态流转)](#三、Java 代码实现(订单状态流转))
    • [1. 抽象状态](#1. 抽象状态)
    • [2. 具体状态:待支付](#2. 具体状态:待支付)
    • [3. 具体状态:已支付](#3. 具体状态:已支付)
    • [4. 具体状态:已发货](#4. 具体状态:已发货)
    • [5. 具体状态:已完成](#5. 具体状态:已完成)
    • [6. 上下文(订单)](#6. 上下文(订单))
    • [7. 客户端测试](#7. 客户端测试)
  • [四、状态模式 VS 策略模式(高频面试)](#四、状态模式 VS 策略模式(高频面试))
  • 五、优缺点
  • 六、应用场景
  • 七、总结

前言

开发中经常遇到对象行为随状态不同而变化 的场景:订单(待支付/已支付/已发货/已完成)、线程(新建/就绪/运行/阻塞/结束)、电梯(开门/关门/运行/停止)。如果用大量 if-else/switch 判断状态,代码臃肿、难以维护、极易出错。状态模式 就是专门解决多状态多行为、状态流转复杂的行为型设计模式。


一、概念

状态模式(State Pattern) 是一种行为型设计模式 ,核心思想:
允许对象在内部状态改变时改变其行为,对象看起来好像修改了它的类。

简单理解:

  • 每种状态 封装成独立的状态类
  • 状态不同,行为完全不同;
  • 状态切换由状态自身或上下文管理;
  • 彻底消灭 if-else/switch

一句话总结:
状态决定行为,状态变,行为就变。


二、核心结构

  1. Context(上下文)
    维护当前状态,将请求委托给当前状态处理。
  2. State(抽象状态)
    定义状态对应的行为接口。
  3. ConcreteState(具体状态)
    实现各自状态下的行为,并负责状态切换。

三、Java 代码实现(订单状态流转)

订单状态流转:
待支付 → 已支付 → 已发货 → 已完成

1. 抽象状态

java 复制代码
public interface OrderState {
    void handle(OrderContext context);
}

2. 具体状态:待支付

java 复制代码
public class WaitPayState implements OrderState {
    @Override
    public void handle(OrderContext context) {
        System.out.println("当前状态:待支付 → 执行支付逻辑");
        context.setState(new PaidState()); // 切换为已支付
    }
}

3. 具体状态:已支付

java 复制代码
public class PaidState implements OrderState {
    @Override
    public void handle(OrderContext context) {
        System.out.println("当前状态:已支付 → 发货");
        context.setState(new DeliverState()); // 切换为已发货
    }
}

4. 具体状态:已发货

java 复制代码
public class DeliverState implements OrderState {
    @Override
    public void handle(OrderContext context) {
        System.out.println("当前状态:已发货 → 确认收货");
        context.setState(new FinishState()); // 切换为已完成
    }
}

5. 具体状态:已完成

java 复制代码
public class FinishState implements OrderState {
    @Override
    public void handle(OrderContext context) {
        System.out.println("当前状态:已完成 → 订单结束");
        // 无后续状态
    }
}

6. 上下文(订单)

java 复制代码
public class OrderContext {
    private OrderState state;

    public OrderContext() {
        // 初始状态:待支付
        state = new WaitPayState();
    }

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

    // 执行当前状态行为
    public void process() {
        state.handle(this);
    }
}

7. 客户端测试

java 复制代码
public class Client {
    public static void main(String[] args) {
        OrderContext order = new OrderContext();
        order.process(); // 待支付 → 已支付
        order.process(); // 已支付 → 已发货
        order.process(); // 已发货 → 已完成
        order.process(); // 已完成
    }
}

输出:

复制代码
当前状态:待支付 → 执行支付逻辑
当前状态:已支付 → 发货
当前状态:已发货 → 确认收货
当前状态:已完成 → 订单结束

四、状态模式 VS 策略模式(高频面试)

对比点 状态模式 策略模式
关注点 状态流转、行为随状态自动变化 算法可互换、平级替换
切换方式 状态自动切换 客户端主动设置
关系 状态之间有流转依赖 策略之间平等独立
典型场景 订单状态、线程状态、电梯状态 支付、促销、排序

五、优缺点

优点

  1. 消除大量 if-else/switch,结构清晰
  2. 状态职责集中,每个状态只做自己的事
  3. 状态切换安全、可控
  4. 符合开闭原则,新增状态只需加类

缺点

  1. 状态多会导致类数量爆炸
  2. 状态流转复杂时,设计难度上升

六、应用场景

  • 订单状态、支付状态、物流状态
  • 线程生命周期(NEW/RUNNABLE/BLOCKED/...)
  • 电梯、门、游戏角色状态
  • 工作流、审批流状态
  • UI 控件状态(可用/禁用/聚焦)

经典框架:

  • Spring Statemachine
  • Quartz 任务状态
  • Netty pipeline 状态

七、总结

  1. 状态模式 = 状态封装 + 行为随状态自动变化
  2. 核心:状态决定行为,状态变,行为就变
  3. 结构:Context + State + 具体状态类
  4. 最适合:多状态、多行为、状态流转复杂场景
相关推荐
砍光二叉树2 小时前
【设计模式】行为型-访问者模式
设计模式·访问者模式
是糖糖啊18 小时前
Google Stitch 用 AI 将想法秒变高保真 UI,并一键导出 Figma / 代码
设计模式·产品经理·产品
SuperEugene21 小时前
前端组件三层架构:页面/业务/基础组件划分,高内聚低耦合|组件化设计基础篇
前端·javascript·vue.js·架构·前端框架·状态模式
Yu_Lijing1 天前
基于C++的《Head First设计模式》笔记——访问者模式
c++·笔记·设计模式
workflower1 天前
未来图景对制造系统提出全面理解、
设计模式·集成测试·软件工程·软件构建·制造·结对编程
程序员小寒1 天前
JavaScript设计模式(七):迭代器模式实现与应用
前端·javascript·设计模式·迭代器模式
刘某某.1 天前
Anthropic 的 Harness 文章解读
状态模式
hnlgzb1 天前
MVC和MVVM设计模式中对应的是什么组件?有什么对应关系?
设计模式·mvc
tobias.b2 天前
软件设计模式:核心术语·名词解释·关联对比
设计模式