状态模式

行为型模式

访问次数: 10

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

类图
classDiagram
    class State {
        <<interface>>
        +handle(context: Context)
    }
    class ConcreteStateA {
        +handle(context: Context)
    }
    class ConcreteStateB {
        +handle(context: Context)
    }
    class Context {
        -state: State
        +setState(state: State)
        +request()
    }
    State <|-- ConcreteStateA
    State <|-- ConcreteStateB
    Context --> State
源代码示例
// 状态接口
interface State {
    void handle(Context context);
}

// 具体状态A
class ConcreteStateA implements State {
    @Override
    public void handle(Context context) {
        System.out.println("Handling in State A");
        context.setState(new ConcreteStateB());
    }
}

// 具体状态B
class ConcreteStateB implements State {
    @Override
    public void handle(Context context) {
        System.out.println("Handling in State B");
        context.setState(new ConcreteStateA());
    }
}

// 上下文类
class Context {
    private State state;
    
    public Context(State state) {
        this.state = state;
    }
    
    public void setState(State state) {
        this.state = state;
    }
    
    public void request() {
        state.handle(this);
    }
}
# Python代码待添加
应用场景
当对象的行为依赖于它的状态,并且必须在运行时根据状态改变其行为时。应用场景包括: 1)电梯控制系统,根据当前状态(开门、关门、运行、停止)执行不同的操作 2)游戏角色状态管理,根据角色状态(正常、受伤、死亡、无敌)执行不同的行为逻辑 3)订单状态管理,根据订单状态(待支付、已支付、已发货、已完成、已取消)执行不同的业务逻辑 4)TCP连接状态管理,根据连接状态(建立连接、数据传输、连接关闭)执行不同的网络操作 5)工作流状态机,根据工作流状态(开始、进行中、暂停、完成、失败)执行不同的处理逻辑 6)用户会话管理,根据用户状态(未登录、已登录、已过期、被锁定)执行不同的权限控制
精选场景详解 —— 电商订单:随状态切换行为
问题背景

订单在待支付、已支付、已发货、已完成、已取消之间流转。同一操作(如 cancel)在不同状态下合法性和副作用不同;用巨型条件分支难以维护。

模式如何解决
选用状态模式:Order 持有 OrderState;各状态类实现 pay、ship、cancel、confirm。状态转换时 setState 到新状态对象,从而改变后续行为。 好处:把「状态 × 行为」分散到状态类,消除巨大 switch;转换规则更清晰。 建模提示:先画状态迁移图,再落到类结构。非法操作可在当前状态中直接拒绝或抛领域异常。
场景模型(角色映射)

将模式中的抽象角色映射到该业务领域的具体类:

classDiagram
    class Order {
        -state: OrderState
        +setState(s: OrderState)
        +pay()
        +ship()
        +cancel()
        +confirm()
    }
    class OrderState {
        <<interface>>
        +pay(order: Order)
        +ship(order: Order)
        +cancel(order: Order)
        +confirm(order: Order)
    }
    class PendingPaymentState {
        +pay(order: Order)
        +cancel(order: Order)
    }
    class PaidState {
        +ship(order: Order)
        +cancel(order: Order)
    }
    class ShippedState {
        +confirm(order: Order)
    }
    class CompletedState
    class CancelledState
    OrderState <|.. PendingPaymentState
    OrderState <|.. PaidState
    OrderState <|.. ShippedState
    OrderState <|.. CompletedState
    OrderState <|.. CancelledState
    Order --> OrderState