你的对象总是表现得像不一样?状态模式帮你根据对象的内部状态变化,改变它的行为,仿佛它有了不同的个性。

在现实生活中,很多时候我们会遇到情绪和环境的变化,这些变化让我们对事情的反应也有所不同。比如,一个人如果开心,可能会笑着做事;如果生气,则可能会暴躁行事;如果疲惫,则可能懒散不愿意动。这种根据状态改变行为的模式,正是状态模式的精髓。

在编程中,状态模式让对象的行为随其内部状态的变化而改变,避免了大量的条件语句和硬编码的状态处理。它就像是切换角色一样,帮你的对象切换不同的“个性”,每种个性都对应着不同的行为。

趣味解读:就像是超级英雄的变身

想象一下,超级英雄可以根据不同的战斗情境变换不同的状态。例如,当面临强大的敌人时,英雄可能切换到“战斗模式”,变得无比强大;当遇到需要智力的任务时,英雄则可能切换到“策略模式”,展现出聪明和机智。这些状态让英雄根据不同的情况展现出不一样的行为。状态模式就像是为你的对象提供了多种“战斗模式”,让它根据不同的状态来做出不同的反应。

Java代码案例:状态模式 - 订单处理

假设你正在开发一个订单系统,订单在不同的状态下(如“已创建”、“已支付”、“已发货”等)会有不同的行为。使用状态模式,你可以为每个订单状态定义一个独立的类,避免在订单类中使用大量的条件判断来处理不同的状态逻辑。

// 1. 状态接口
interface OrderState {
    void handleRequest(OrderContext context);
}
​
// 2. 具体状态 - 已创建
class CreatedState implements OrderState {
    @Override
    public void handleRequest(OrderContext context) {
        System.out.println("订单已创建,准备付款...");
        context.setState(new PaidState());  // 切换到已支付状态
    }
}
​
// 3. 具体状态 - 已支付
class PaidState implements OrderState {
    @Override
    public void handleRequest(OrderContext context) {
        System.out.println("订单已支付,准备发货...");
        context.setState(new ShippedState());  // 切换到已发货状态
    }
}
​
// 4. 具体状态 - 已发货
class ShippedState implements OrderState {
    @Override
    public void handleRequest(OrderContext context) {
        System.out.println("订单已发货,等待收货...");
        context.setState(new DeliveredState());  // 切换到已送达状态
    }
}
​
// 5. 具体状态 - 已送达
class DeliveredState implements OrderState {
    @Override
    public void handleRequest(OrderContext context) {
        System.out.println("订单已送达,交易完成!");
    }
}
​
// 6. 上下文 - 订单类
class OrderContext {
    private OrderState currentState;
​
    public OrderContext() {
        currentState = new CreatedState();  // 初始状态
    }
​
    public void setState(OrderState state) {
        currentState = state;
    }
​
    public void handleRequest() {
        currentState.handleRequest(this);
    }
}
​
// 7. 客户端代码
public class Main {
    public static void main(String[] args) {
        // 创建一个订单上下文
        OrderContext order = new OrderContext();
​
        // 订单状态发生变化
        order.handleRequest();  // 订单已创建,准备付款...
        order.handleRequest();  // 订单已支付,准备发货...
        order.handleRequest();  // 订单已发货,等待收货...
        order.handleRequest();  // 订单已送达,交易完成!
    }
}

解析:

  • 状态接口OrderState 定义了 handleRequest() 方法,用于处理不同状态下的请求。

  • 具体状态CreatedStatePaidStateShippedStateDeliveredState 分别代表订单的不同状态,每个状态对应着不同的行为。

  • 上下文类OrderContext 持有当前状态的引用,并通过 setState() 方法切换状态。handleRequest() 方法会调用当前状态的 handleRequest() 方法,触发状态的变化。

  • 客户端代码:在 Main 类中,创建了一个订单上下文并调用 handleRequest() 方法。随着订单状态的变化,系统会自动切换状态并执行相应的行为。

运行结果:

订单已创建,准备付款...
订单已支付,准备发货...
订单已发货,等待收货...
订单已送达,交易完成!

实际应用场景

  1. 游戏中的角色状态:在很多游戏中,角色的行为会根据不同的状态变化。例如,角色的生命值高时,它可能主动进攻;生命值低时,角色可能变得防守。状态模式可以帮助管理这些不同的行为。

  2. 工作流引擎:许多业务流程系统(如审批流程、订单处理等)都会经历多个状态。通过状态模式,可以根据当前的流程状态动态处理每个阶段的任务,避免了冗长的条件判断。

  3. 网络连接状态管理:在处理网络连接时,不同的连接状态(如连接中、已连接、断开连接等)会有不同的行为。状态模式可以帮助你为每个状态定义不同的处理逻辑。

总结

状态模式通过将对象的行为与其状态相关联,让对象在不同状态下展现不同的行为。通过将每个状态封装为独立的类,避免了大量的条件语句和复杂的逻辑结构。状态模式不仅能增强代码的可维护性和可扩展性,还能提升系统的灵活性,使得状态切换变得更加清晰和易于管理。