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

文章目录

  • 前言
  • 一、概念
  • 二、核心结构
  • [三、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. 最适合:多状态、多行为、状态流转复杂场景
相关推荐
Lands2 小时前
推荐一下配合agent开发的工具
设计模式·agent
前端不太难5 小时前
用 ArkUI 写一个小游戏,体验如何?
状态模式·harmonyos
不才小强5 小时前
行为型设计模式
设计模式
誰能久伴不乏6 小时前
Qt 混合编程核心原理:C++ 与 QML 通信机制详解
linux·c++·qt·架构·状态模式
ximu_polaris7 小时前
设计模式(C++)-结构型模式-享元模式
c++·设计模式·享元模式
geovindu7 小时前
go: Facade Pattern
设计模式·golang·外观模式
ZC跨境爬虫7 小时前
UI前端美化技能提升日志day5:从布局优化到CSS继承原理深度解析
前端·css·ui·html·状态模式
前端不太难8 小时前
如何设计 Agent 的“最小权限原则”
人工智能·状态模式·agent
旷世奇才李先生8 小时前
React 18\+TypeScript实战: hooks封装与组件设计模式
react.js·设计模式·typescript
白夜11178 小时前
C++设计模式(高内聚,低耦合)
c++·设计模式