12.状态模式

文章目录


状态模式

介绍

状态模式它允许一个对象在其内部状态改变时改变其行为,使对象看起来似乎修改了其类。状态模式的主要目的是将对象的状态封装成不同的类,并将对象的行为委托给当前状态。

组成

  1. Context(环境): 维护一个对具体状态的引用,维护一个状态对象,并将与状态相关的操作委托给当前状态对象。
  2. State(状态): 定义一个接口或抽象类,封装了与Context的一个特定状态相关的行为。
  3. ConcreteState(具体状态): 实现了State接口,每个具体状态类都提供了在状态改变时处理的具体行为。

结构图

场景

假设我们有一个订单处理系统,订单在不同的状态下可以执行不同的操作,比如创建、支付、发货、完成等

版本1.0

java 复制代码
// 不使用状态模式的订单类
class OrderWithoutState {
    private String state;

    public OrderWithoutState() {
        // 初始状态为创建状态
        state = "Created";
    }

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

    public void processOrder() {
        if ("Created".equals(state)) {
            System.out.println("Order created, waiting for payment");
            // 可以执行创建订单后的其他逻辑
        } else if ("Paid".equals(state)) {
            System.out.println("Payment received, preparing for shipment");
            // 可以执行支付后的其他逻辑
        } else if ("Shipped".equals(state)) {
            System.out.println("Order shipped, waiting for confirmation");
            // 可以执行发货后的其他逻辑
        } else if ("Completed".equals(state)) {
            System.out.println("Order completed, thank you for your purchase");
            // 可以执行订单完成后的其他逻辑
        }
    }
}
java 复制代码
// 客户端
public class WithoutStatePatternExample {
    public static void main(String[] args) {
        OrderWithoutState order = new OrderWithoutState();

        // 创建订单
        order.processOrder();

        // 支付订单
        order.setState("Paid");
        order.processOrder();

        // 发货
        order.setState("Shipped");
        order.processOrder();

        // 完成订单
        order.setState("Completed");
        order.processOrder();
    }
}

问题

上面的实现中,订单类包含一个表示状态的字符串属性,通过条件语句判断当前订单状态,并执行相应的逻辑。这种实现方式会导致代码中出现大量的条件判断,难以维护,并且不符合开闭原则,当需要添加新的订单状态时,需要修改原有的代码。

使用状态模式版本

java 复制代码
// 状态接口
interface OrderState {
    void processOrder(OrderContext context);
}
java 复制代码
// 具体状态1:创建状态
class CreatedState implements OrderState {
    @Override
    public void processOrder(OrderContext context) {
        System.out.println("Order created, waiting for payment");
        // 可以执行创建订单后的其他逻辑
    }
}

// 具体状态2:支付状态
class PaidState implements OrderState {
    @Override
    public void processOrder(OrderContext context) {
        System.out.println("Payment received, preparing for shipment");
        // 可以执行支付后的其他逻辑
    }
}

// 具体状态3:发货状态
class ShippedState implements OrderState {
    @Override
    public void processOrder(OrderContext context) {
        System.out.println("Order shipped, waiting for confirmation");
        // 可以执行发货后的其他逻辑
    }
}

// 具体状态4:完成状态
class CompletedState implements OrderState {
    @Override
    public void processOrder(OrderContext context) {
        System.out.println("Order completed, thank you for your purchase");
        // 可以执行订单完成后的其他逻辑
    }
}
java 复制代码
// 环境类:订单上下文
class OrderContext {
    private OrderState currentState;

    public OrderContext() {
        // 初始状态为创建状态
        currentState = new CreatedState();
    }

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

    public void processOrder() {
        currentState.processOrder(this);
    }
}
java 复制代码
// 客户端
public class StatePatternExample {
    public static void main(String[] args) {
        OrderContext order = new OrderContext();

        // 创建订单
        order.processOrder();

        // 支付订单
        order.setState(new PaidState());
        order.processOrder();

        // 发货
        order.setState(new ShippedState());
        order.processOrder();

        // 完成订单
        order.setState(new CompletedState());
        order.processOrder();
    }
}

在这个版本的实现中,我们定义了订单的不同状态,并使用状态模式来处理订单状态的变化。每个具体状态类都实现了 OrderState 接口,提供了处理订单的具体逻辑。OrderContext 类是环境类,维护了当前订单的状态,并通过委托给当前状态对象来执行相应的操作。


总结

优点

  1. 封装性好: 将每个状态封装到一个类中,使得每个状态的实现对其他状态都是独立的,更容易添加新的状态。

  2. 可扩展性好: 容易添加新的状态类,符合开闭原则。

  3. 避免了使用大量的条件语句: 状态模式将不同状态的逻辑分离,避免了使用大量的条件语句来判断当前状态。

相关推荐
雪人.1 分钟前
Spring常见面试题(2026版30道面试题)
java·后端·spring
温暖小土3 分钟前
深入理解 Spring Boot 配置加载顺序:外部化配置的艺术
java·springboot
小林rr7 分钟前
深入探索 C++:现代特性、工程实践与性能优化全解
java·c++·性能优化
专注数据的痴汉28 分钟前
「数据获取」全国民用运输机场吞吐量排名(2006-2024)
java·大数据·服务器·数据库·信息可视化
悟空码字1 小时前
无缝集成指南,SpringBoot三步接入华为云短信服务
java·springboot·编程技术·后端开发·华为云短信
linweidong1 小时前
中科曙光Java后端开发面试题及参考答案
分布式·设计模式·spring mvc·tcp协议·三次握手·后端开发·java面经
E_ICEBLUE1 小时前
【2026 最新教程】Java 自动化提取 PDF 表格:从文本到 Excel/CSV 的全场景实现
java·pdf·自动化
C雨后彩虹1 小时前
无向图染色
java·数据结构·算法·华为·面试
J_HelloWorld1 小时前
缺页中断:Java高性能存储的隐形推手
java·缺页中断
一代明君Kevin学长1 小时前
记录一个上手即用的Spring全局返回值&异常处理框架
java·网络·python·spring