• 状态模式(State Pattern)


    状态模式(State Pattern)是面向对象设计模式中的一种行为模式,它允许一个对象在其内部状态改变时改变它的行为。状态模式的核心意图是将状态相关的逻辑从主类中分离出来,使得每个状态都成为独立的对象,这样可以简化原本复杂的条件语句,并且提高代码的可维护性和扩展性。

    意图

    允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

    • 将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
    • 通过切换内部状态来改变对象的行为。
    • 让状态转换显得更加明确和可控。

    结构

    状态模式包含以下几种角色:

    • Context(环境类):定义了客户端感兴趣的接口,并维护一个具体状态子类的实例,这个实例定义当前的状态。
    • State(抽象状态角色):定义了一个或一组接口,表示支持的所有状态所共有的行为。
    • ConcreteState(具体状态角色):每一个具体状态提供一个方法,该方法实现了在Context的一个特定状态下所表现的行为。

    结构图

    +-------------------+       +------------------+
    |    Context        |-------|   State (抽象)   |
    +-------------------+       +------------------+
    | -state: State     |<------| + handle()       |
    +-------------------+       +------------------+
    | + request()       |       |                  |
    +-------------------+       +------------------+
                                ^                 ^
                                |                 |
                                |                 |
                    +-----------+-----------------+
                    |                             |
    +---------------v-------------+       +-------v---------+
    | ConcreteStateA (具体状态A)  |       |ConcreteStateB  |
    +----------------------------+       +---------------+
    | + handle()                  |       | + handle()    |
    +----------------------------+       +---------------+
    

    在这个图中,Context持有一个State类型的引用,它可以指向任何具体的State子类。当Contextrequest()方法被调用时,实际上是由当前状态的handle()方法来处理请求。State接口定义了所有具体状态都需要实现的方法。

    适用性

    • 当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时。
    • 代码中存在大量与状态相关的条件语句(如if-else或者switch-case),这些语句难以维护和扩展。
    • 当状态转换是复杂且具有约束时,状态模式可以帮助清晰地定义并控制状态之间的转换。

    状态模式可以用来管理那些需要随时间而变化的对象行为,并且能够帮助我们避免大量的条件分支语句,让代码变得更加清晰和易于理解。在实际应用中,比如工作流引擎、游戏中的角色状态等场景下,状态模式都是十分有用的。

    应用举例 (处理订单的状态变化)

    状态模式在Java开发中有很多经典的应用场景,其中一个非常典型的例子是处理订单的状态变化。在电子商务系统中,一个订单可能会经历多种状态,如创建、支付、发货、完成和取消等。每个状态下可以执行的操作不同,并且从一种状态到另一种状态的转换规则也可能很复杂。使用状态模式可以很好地管理这种状态的变化。

    场景描述

    假设我们正在为一个在线购物网站开发后端服务。我们需要处理用户的订单,而订单可能有以下几种状态:

    • 新创建(New):用户刚刚下单。
    • 已支付(Paid):用户已经付款。
    • 已发货(Shipped):商品已经发出。
    • 已完成(Completed):用户收到商品并且确认收货。
    • 已取消(Cancelled):订单被取消。

    对于每种状态,允许的操作是不同的。例如,在“新创建”状态下,用户可以选择支付或取消订单;而在“已支付”状态下,用户不能再次支付,但是可以等待发货或者申请退款。

    状态模式实现

    定义抽象状态接口
    public interface OrderState {
        void handle(Order order);
    }
    
    实现具体状态
    public class NewOrderState implements OrderState {
        @Override
        public void handle(Order order) {
            System.out.println("Order is in New state. Waiting for payment.");
            // 可以进行支付操作
            order.setState(new PaidOrderState());
        }
    }
    
    public class PaidOrderState implements OrderState {
        @Override
        public void handle(Order order) {
            System.out.println("Order is paid. Preparing to ship.");
            // 可以进行发货操作
            order.setState(new ShippedOrderState());
        }
    }
    
    // 其他状态类省略...
    
    定义环境类(订单)
    public class Order {
        private OrderState state;
    
        public Order() {
            this.state = new NewOrderState();  // 默认为新创建状态
        }
    
        public void setState(OrderState state) {
            this.state = state;
        }
    
        public void request() {
            state.handle(this);
        }
    }
    
    使用示例
    public class Client {
        public static void main(String[] args) {
            Order order = new Order();
            order.request();  // 输出: Order is in New state. Waiting for payment.
            order.request();  // 输出: Order is paid. Preparing to ship.
            // 更多的状态转换...
        }
    }
    

    在这个简单的例子中,Order对象根据当前的状态来决定如何处理请求。当调用request()方法时,实际是由当前状态的handle()方法来处理逻辑。这样做的好处是可以将不同状态下的行为封装起来,避免了复杂的条件判断,并且易于添加新的状态或修改现有状态的行为。

  • 相关阅读:
    【从零开始游戏开发】Unity 数据存储和读取 PlayerPrefs、序列化、JSON | 全面总结 |建议收藏
    C++函数模板和类模板(基础+进阶)
    AttributeError: module ‘dgl‘ has no attribute ‘batch_hetero‘
    【Netty】Netty 编解码器(十四)
    OpenCV 图像的几何变换
    K8S 1.20 弃用 Docker 评估之 Docker 和 OCI 镜像格式的差别
    【Linux】基本的指令(三)
    20221206英语学习
    数据结构 堆排序
    探索4D毫米波雷达和摄像头在自动驾驶中的潜力
  • 原文地址:https://blog.csdn.net/QQ657205470/article/details/143303294