# 状态模式

# 概念

状态模式是一种行为型设计模式,允许对象在其内部状态改变时改变其行为,使对象看似修改了自身类。其核心思想是将与状态相关的行为封装到独立的状态类中,并通过委托方式动态切换状态逻辑,从而将状态转换逻辑局部化到具体状态类中。

# 作用

1.消除大量条件分支(如 if-else),避免状态判断逻辑分散在多个方法中。

2.将状态转换逻辑集中管理到具体状态类,提高逻辑的内聚性。

3.提高代码可维护性和扩展性,新增状态时无需修改现有代码(符合开闭原则)。

# 场景

1.对象行为依赖多个状态,且状态转换频繁(如电商订单状态流转)。

2.需要消除大量状态判断分支(如游戏角色状态、工作流审批状态)。

3.需要清晰分离不同状态的业务逻辑,避免状态逻辑耦合。

# 举例

状态模式实现,订单状态场景:

// 状态接口
interface OrderState {
    void complete(Order order);
    void cancel(Order order);
}
// 新建状态
class NewState implements OrderState {
    @Override
    public void complete(Order order) {
        System.out.println("订单完成!");
        order.setState(new CompletedState());
    }

    @Override
    public void cancel(Order order) {
        System.out.println("订单已取消!");
        order.setState(new CancelledState());
    }
}
// 已完成状态
class CompletedState implements OrderState {
    @Override
    public void complete(Order order) {
        System.out.println("已完成订单不可重复完成!");
    }

    @Override
    public void cancel(Order order) {
        System.out.println("已完成订单不可取消!");
    }
}
// 已取消状态
class CancelledState implements OrderState {
    @Override
    public void complete(Order order) {
        System.out.println("已取消订单不可完成!");
    }

    @Override
    public void cancel(Order order) {
        System.out.println("已取消订单不可重复取消!");
    }
}
// 订单类
class Order {
    private OrderState state;

    public Order() {
        this.state = new NewState(); // 初始状态
    }

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

    // 委托给当前状态处理
    public void complete() {
        state.complete(this);
    }

    public void cancel() {
        state.cancel(this);
    }
}
// 测试类
public class StatePatternDemo {
    public static void main(String[] args) {
        Order order = new Order();

        order.complete(); // 输出:订单完成!
        order.cancel();   // 输出:已完成订单不可取消!

        order = new Order();
        order.cancel();   // 输出:订单已取消!
        order.complete(); // 输出:已取消订单不可完成!
    }
}

# 反例(不使用状态模式)

// 订单类(条件分支实现)
class Order {
    private String state; // "NEW", "COMPLETED", "CANCELLED"

    public void complete() {
        if ("NEW".equals(state)) {
            System.out.println("订单完成!");
            state = "COMPLETED";
        } else if ("COMPLETED".equals(state)) {
            System.out.println("已完成订单不可重复完成!");
        } else if ("CANCELLED".equals(state)) {
            System.out.println("已取消订单不可完成!");
        }
    }

    public void cancel() {
        if ("NEW".equals(state)) {
            System.out.println("订单已取消!");
            state = "CANCELLED";
        } else if ("COMPLETED".equals(state)) {
            System.out.println("已完成订单不可取消!");
        } else if ("CANCELLED".equals(state)) {
            System.out.println("已取消订单不可重复取消!");
        }
    }
}

# 原理

状态模式通过定义状态接口,将每个状态的具体行为封装到独立的状态类中。对象持有当前状态对象,当状态需要转换时,通过委托方式调用具体状态类的逻辑,并替换为新的状态对象。这种方式将状态逻辑与对象主体解耦,使状态转换逻辑集中管理,避免了条件分支的扩散。

# 缺点

1.增加类的数量:每个状态需对应一个具体状态类,小规模场景可能显得冗余。

2.小规模场景可能过度设计:状态简单且转换不频繁时,引入状态模式可能增加复杂度。

3.状态间依赖可能增加复杂度:若状态转换逻辑涉及多个状态交互,需额外管理状态间的依赖关系。

总结

状态模式通过封装状态逻辑到独立类中,动态切换状态对象,有效消除了条件分支,提升了代码的可维护性和扩展性。适用于状态多、转换频繁且逻辑复杂的场景,但需权衡类数量增加的代价,避免在小规模场景中过度使用。



微信公众号

QQ交流群
原创网站开发,偏差难以避免。

如若发现错误,诚心感谢反馈。

愿你倾心相念,愿你学有所成。

愿你朝华相顾,愿你前程似锦。