行为型设计模式——状态模式

状态模式(State Pattern) 是一种行为设计模式,将状态封装为独立的类,并将动作委托给代表当前状态的对象。允许对象在其内部状态改变时改变其行为。

特点

1、将状态相关的行为封装在不同的状态类中;2、上下文对象(Context)的行为会随着其状态的改变而改变;2、消除了复杂的条件判断语句,使代码更易于维护和扩展

结构

状态模式结构包括三个部分:

  1. Context(上下文)

    • 维护一个ConcreteState子类的实例,定义当前状态

    • 提供客户端调用的接口,将请求委托给当前状态对象处理

  2. State(状态接口)

    • 定义状态行为的接口

    • 封装与Context特定状态相关的行为

  3. ConcreteState(具体状态)

    • 实现State接口

    • 实现与Context某个状态相关的行为

UML对象图如下:

代码示例

java 复制代码
// 1. 状态接口
interface OrderState {
    // 订单处理
    void process(OrderContext order);
    // 订单取消
    void cancel(OrderContext order);
    // 订单发货
    void ship(OrderContext order);
    // 订单送达
    void deliver(OrderContext order);
    String getStateName();
}

// 2. 抽象状态类(提供默认实现)
abstract class AbstractOrderState implements OrderState {
    @Override
    public void process(OrderContext order) {
        throw new UnsupportedOperationException("当前状态不支持此操作");
    }
    
    @Override
    public void cancel(OrderContext order) {
        throw new UnsupportedOperationException("当前状态不支持此操作");
    }
    
    @Override
    public void ship(OrderContext order) {
        throw new UnsupportedOperationException("当前状态不支持此操作");
    }
    
    @Override
    public void deliver(OrderContext order) {
        throw new UnsupportedOperationException("当前状态不支持此操作");
    }
}

// 3. 具体状态类
class NewOrderState extends AbstractOrderState {
    @Override
    public void process(OrderContext order) {
        System.out.println("处理新订单...");
        order.setState(new ProcessingOrderState());
    }
    
    @Override
    public void cancel(OrderContext order) {
        System.out.println("取消新订单");
        order.setState(new CancelledOrderState());
    }
    
    @Override
    public String getStateName() {
        return "新订单";
    }
}

class ProcessingOrderState extends AbstractOrderState {
    @Override
    public void ship(OrderContext order) {
        System.out.println("订单已发货");
        order.setState(new ShippedOrderState());
    }
    
    @Override
    public void cancel(OrderContext order) {
        System.out.println("取消处理中的订单");
        order.setState(new CancelledOrderState());
    }
    
    @Override
    public String getStateName() {
        return "处理中";
    }
}

class ShippedOrderState extends AbstractOrderState {
    @Override
    public void deliver(OrderContext order) {
        System.out.println("订单已送达");
        order.setState(new DeliveredOrderState());
    }
    
    @Override
    public String getStateName() {
        return "已发货";
    }
}

class DeliveredOrderState extends AbstractOrderState {
    @Override
    public String getStateName() {
        return "已送达";
    }
}

class CancelledOrderState extends AbstractOrderState {
    @Override
    public String getStateName() {
        return "已取消";
    }
}

// 4. 上下文类
class OrderContext {
    private OrderState currentState;
    private String orderId;
    
    public OrderContext(String orderId) {
        this.orderId = orderId;
        this.currentState = new NewOrderState();
    }
    
    public void setState(OrderState state) {
        this.currentState = state;
        System.out.println("订单 [" + orderId + "] 状态变更为: " + state.getStateName());
    }
    
    public void process() {
        currentState.process(this);
    }
    
    public void cancel() {
        currentState.cancel(this);
    }
    
    public void ship() {
        currentState.ship(this);
    }
    
    public void deliver() {
        currentState.deliver(this);
    }
    
    public String getCurrentState() {
        return currentState.getStateName();
    }
}

// 5. 客户端代码
public class OrderStateDemo {
    public static void main(String[] args) {
        OrderContext order = new OrderContext("ORD001");
        System.out.println("初始状态: " + order.getCurrentState());
        
        try {
            order.process();    // 新订单 -> 处理中
            order.ship();       // 处理中 -> 已发货
            order.deliver();    // 已发货 -> 已送达
            
            // 尝试非法操作
            System.out.println("\n尝试取消已送达的订单:");
            order.cancel();     // 应该抛出异常
        } catch (Exception e) {
            System.out.println("操作失败: " + e.getMessage());
        }
        
        System.out.println("\n=== 另一个订单 ===");
        OrderContext order2 = new OrderContext("ORD002");
        order2.cancel();  // 新订单 -> 已取消
    }
}

适合场景

  1. 对象行为依赖于状态 :一个对象的行为取决于它的状态,在运行时根据状态改变行为

  2. 大量条件判断:操作中含有庞大的多分支条件语句,且这些分支依赖于对象的状态

  3. 状态转换复杂:状态转换逻辑复杂或状态数量较多

  4. 需要维护状态历史:需要跟踪状态变化历史

应用案例

  1. 工作流引擎:文档审批流程、订单处理流程

  2. 游戏开发:角色状态(站立、行走、奔跑、跳跃、攻击)

  3. 网络连接:连接状态(建立连接、已连接、断开连接、重新连接)

  4. UI组件:按钮状态(正常、悬停、按下、禁用)

  5. 电梯控制:电梯运行状态(停止、上行、下行、故障)

  6. 自动售货机:商品选择、付款、出货等状态

  7. 线程状态管理:新建、就绪、运行、阻塞、终止

优缺点

优点:

1、单一职责原则 :将与特定状态相关的代码组织到独立的类中;2、开闭原则 :增加新状态时无需修改现有状态类或上下文;3、消除条件语句 :减少上下文中复杂的条件判断;4、状态转换显式化 :使状态转换更加明确;5、提高可维护性:状态逻辑局部化,易于理解和维护

缺点:

1、类数量增加 :每个状态都需要一个对应的类,可能导致类数量膨胀;2、过度设计 :如果状态数量很少或状态转换简单,使用状态模式可能增加复杂性;3、状态共享:不同上下文之间共享状态对象时需要确保线程安全

相关推荐
花大师9 分钟前
基于深度学习的鼠标轨迹真实性检测系统
后端
小江的记录本27 分钟前
【Spring全家桶】Spring Cloud 2023.0.x:微服务核心理论、CAP/BASE定理(附《思维导图》+《面试高频考点清单》)
java·spring boot·后端·spring·spring cloud·微服务·面试
Solis程序员30 分钟前
缓存三剑客预防策略
java·spring·缓存
我登哥MVP42 分钟前
Spring Boot 从“会用”到“精通”:Model-Map原理
java·spring boot·后端·spring·servlet·maven·mybatis
程序猿乐锅1 小时前
【苍穹外卖|Day02】后台接口自测闭环:Token、DTO 与 yml 配置
java·开发语言
心之伊始1 小时前
Spring Boot Actuator + Micrometer 自定义业务指标:不只是健康检查
java·架构·源码分析·csdn
Eason_LYC1 小时前
【GetShell 实战】CVE-2026-34486 Tomcat 加密拦截器绕过:从漏洞验证到反弹 Shell 全流程
java·渗透测试·tomcat·java反序列化·rce·远程代码执行漏洞·cve-2026-34486
qq_2518364571 小时前
基于java 税务管理系统设计与实现
java·开发语言
超梦dasgg1 小时前
Java 生产环境分布式定时任务全解(实战落地版)
java·开发语言·分布式