设计模式之-状态模式

一、定义

状态模式(State Pattern):允许一个对象在其内部状态改变时,改变其行为。看起来就像是改变了这个对象的类。

通俗理解:对象内部状态不同,它“表现出来”的行为也不同,状态之间可自由转换。

二、适用场景

  • 对象有多种状态,且状态之间存在明显切换逻辑;
  • 状态对应的行为复杂,使用 if-else 难以维护;
  • 希望将状态行为解耦,提高扩展性和可读性;
  • 适用于工作流引擎、订单系统、审批流、游戏角色等。

三、核心角色

角色

说明

Context

环境类,持有当前状态,提供行为方法,并将请求委托给状态对象执行

State(状态接口)

抽象状态,定义所有状态类的共同行为方法

ConcreteState

具体状态类,实现不同状态下的行为逻辑

四、UML 类图


+-----------------+
|     Context     |
|-----------------|
| - state: State  |
| + setState()    |
| + request()     |
+-----------------+
        |
        v
+-----------------+         +--------------------+
|     State       |<------> |  ConcreteStateA    |
| + handle()      |         +--------------------+
+-----------------+         | + handle()         |
                            +--------------------+

                             +--------------------+
                             |  ConcreteStateB    |
                             +--------------------+
                             | + handle()         |
                             +--------------------+

五、真实业务场景示例(含类角色与详细注释)

🧾 场景说明:

订单系统 为例,订单具有不同的状态,如:待支付已支付已发货已完成。每种状态下支持的操作不同。

1. 抽象状态接口(State 角色)

// State:抽象状态接口,定义所有订单状态共有的操作
public interface OrderState {
    void pay();      // 支付操作
    void deliver();  // 发货操作
    void receive();  // 收货操作
}

2. 具体状态类(ConcreteState 角色)

// ConcreteState:待支付状态,只能执行支付
public class PendingPaymentState implements OrderState {

    private final OrderContext context;

    public PendingPaymentState(OrderContext context) {
        this.context = context;
    }

    @Override
    public void pay() {
        System.out.println("订单已支付,进入发货流程");
        context.setState(new PaidState(context)); // 状态流转
    }

    @Override
    public void deliver() {
        System.out.println("当前为待支付状态,不能发货!");
    }

    @Override
    public void receive() {
        System.out.println("当前为待支付状态,不能收货!");
    }
}

// ConcreteState:已支付状态,只能执行发货
public class PaidState implements OrderState {

    private final OrderContext context;

    public PaidState(OrderContext context) {
        this.context = context;
    }

    @Override
    public void pay() {
        System.out.println("订单已支付,请勿重复操作!");
    }

    @Override
    public void deliver() {
        System.out.println("订单已发货,等待用户收货");
        context.setState(new DeliveredState(context));
    }

    @Override
    public void receive() {
        System.out.println("订单未发货,不能收货!");
    }
}

// ConcreteState:已发货状态,只能执行收货
public class DeliveredState implements OrderState {

    private final OrderContext context;

    public DeliveredState(OrderContext context) {
        this.context = context;
    }

    @Override
    public void pay() {
        System.out.println("订单已支付,请勿重复操作!");
    }

    @Override
    public void deliver() {
        System.out.println("订单已发货,请勿重复发货!");
    }

    @Override
    public void receive() {
        System.out.println("用户已收货,订单完成");
        context.setState(new CompletedState(context));
    }
}

// ConcreteState:已完成状态,所有操作无效
public class CompletedState implements OrderState {

    private final OrderContext context;

    public CompletedState(OrderContext context) {
        this.context = context;
    }

    @Override
    public void pay() {
        System.out.println("订单已完成,不能再支付");
    }

    @Override
    public void deliver() {
        System.out.println("订单已完成,不能再发货");
    }

    @Override
    public void receive() {
        System.out.println("订单已完成,不能再收货");
    }
}

3. 环境类(Context 角色)

// Context:订单上下文,持有当前状态,并将操作委托给状态对象
public class OrderContext {

    private OrderState currentState;

    public OrderContext() {
        // 默认状态为待支付
        this.currentState = new PendingPaymentState(this);
    }

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

    public void pay() {
        currentState.pay();
    }

    public void deliver() {
        currentState.deliver();
    }

    public void receive() {
        currentState.receive();
    }
}

4. 客户端测试类(Client 角色)

public class StatePatternTest {
    public static void main(String[] args) {
        OrderContext order = new OrderContext();

        order.pay();      // 支付
        order.deliver();  // 发货
        order.receive();  // 收货

        // 再次尝试支付
        order.pay();      // 已完成状态下操作无效
    }
}

💡 类与角色对照表

类名

模式角色

说明

OrderState

State

抽象状态接口,定义行为方法

PendingPaymentState

ConcreteState

待支付状态

PaidState

ConcreteState

已支付状态

DeliveredState

ConcreteState

已发货状态

CompletedState

ConcreteState

已完成状态

OrderContext

Context

上下文,持有当前状态,行为委托给状态对象

StatePatternTest

Client

客户端测试代码

六、优缺点分析(Pros & Cons)

✅ 优点

优点

说明

封装状态行为

每个状态行为独立,职责清晰,代码整洁

避免冗长条件判断

替代 if-else

switch

,更易扩展

状态可扩展

新增状态无需修改现有代码,符合开闭原则

更易维护

状态之间流转清晰,业务逻辑集中


❌ 缺点

缺点

说明

类数量增多

每个状态都是一个类,状态多时文件多

状态切换可能复杂

多状态之间依赖较多时,流转逻辑需要协调

若状态行为简单

使用模式反而显得结构臃肿

七、现实应用场景

场景

描述

审批流程

申请 → 审核中 → 审批通过/拒绝

订单流程

下单 → 支付 → 发货 → 收货 → 完成

游戏角色

正常状态 → 受伤状态 → 死亡状态

工作流引擎

各流程节点状态切换

TCP 连接

CLOSED、LISTEN、ESTABLISHED 等状态

八、总结(Summary)

状态模式是一种强大的行为型设计模式,适用于状态控制复杂、行为变化明显的业务流程。它通过封装状态行为,使状态逻辑独立清晰,大大提高了系统的可维护性和扩展性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码蚁Q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值