Skip to content

状态

更新: 6/28/2025 字数: 0 字 时长: 0 分钟

定义

状态模式 (State Pattern) 允许一个对象在其内部状态改变时改变它的行为,使对象看起来似乎修改了它的类。该模式将状态封装成独立的类,并将动作委托到代表当前状态的对象。

角色

  • 上下文 (Context):维护具体状态实例,定义客户端接口
  • 抽象状态 (State):定义状态接口,封装上下文特定行为
  • 具体状态 (ConcreteState):实现状态接口,每个子类对应一种状态
  • 客户端 (Client):使用上下文对象,触发状态转换

实现

电梯状态控制

java
// 抽象状态
public interface ElevatorState {
    void openDoors();
    void closeDoors();
    void move();
    void stop();
}

// 具体状态:开门状态
public class OpenState implements ElevatorState {
    private ElevatorContext context;
    
    public OpenState(ElevatorContext context) {
        this.context = context;
    }
    
    @Override
    public void openDoors() {
        System.out.println("门已经是开着的");
    }
    
    @Override
    public void closeDoors() {
        System.out.println("正在关门...");
        context.setState(context.getClosedState());
    }
    
    @Override
    public void move() {
        System.out.println("无法移动,门开着");
    }
    
    @Override
    public void stop() {
        System.out.println("已经停止");
    }
}

// 具体状态:关门状态
public class ClosedState implements ElevatorState {
    private ElevatorContext context;
    
    public ClosedState(ElevatorContext context) {
        this.context = context;
    }
    
    @Override
    public void openDoors() {
        System.out.println("正在开门...");
        context.setState(context.getOpenState());
    }
    
    @Override
    public void closeDoors() {
        System.out.println("门已经是关着的");
    }
    
    @Override
    public void move() {
        System.out.println("正在移动...");
        context.setState(context.getMovingState());
    }
    
    @Override
    public void stop() {
        System.out.println("已经停止");
    }
}

// 具体状态:移动状态
public class MovingState implements ElevatorState {
    private ElevatorContext context;
    
    public MovingState(ElevatorContext context) {
        this.context = context;
    }
    
    @Override
    public void openDoors() {
        System.out.println("无法开门,正在移动");
    }
    
    @Override
    public void closeDoors() {
        System.out.println("门已经是关着的");
    }
    
    @Override
    public void move() {
        System.out.println("已经在移动中");
    }
    
    @Override
    public void stop() {
        System.out.println("正在停止...");
        context.setState(context.getClosedState());
    }
}

// 上下文:电梯控制
public class ElevatorContext {
    private ElevatorState openState;
    private ElevatorState closedState;
    private ElevatorState movingState;
    private ElevatorState currentState;
    
    public ElevatorContext() {
        openState = new OpenState(this);
        closedState = new ClosedState(this);
        movingState = new MovingState(this);
        currentState = closedState; // 初始状态为关门
    }
    
    public void setState(ElevatorState state) {
        this.currentState = state;
    }
    
    // 委托操作到当前状态
    public void openDoors() {
        currentState.openDoors();
    }
    
    public void closeDoors() {
        currentState.closeDoors();
    }
    
    public void move() {
        currentState.move();
    }
    
    public void stop() {
        currentState.stop();
    }
    
    // 状态获取方法
    public ElevatorState getOpenState() {
        return openState;
    }
    
    public ElevatorState getClosedState() {
        return closedState;
    }
    
    public ElevatorState getMovingState() {
        return movingState;
    }
}

// 使用示例
public class ElevatorDemo {
    public static void main(String[] args) {
        ElevatorContext elevator = new ElevatorContext();
        
        elevator.openDoors();  // 开门
        elevator.closeDoors(); // 关门
        elevator.move();       // 移动
        elevator.stop();       // 停止
        elevator.openDoors();  // 开门
        
        System.out.println("--- 尝试非法操作 ---");
        elevator.move();       // 移动(失败,门开着)
        elevator.closeDoors(); // 关门
        elevator.move();       // 移动
    }
}

订单状态系统

java
// 订单状态接口
public interface OrderState {
    void confirm(OrderContext context);
    void cancel(OrderContext context);
    void ship(OrderContext context);
    void deliver(OrderContext context);
}

// 具体状态:新建状态
public class NewState implements OrderState {
    @Override
    public void confirm(OrderContext context) {
        System.out.println("订单已确认");
        context.setState(context.getConfirmedState());
    }
    
    @Override
    public void cancel(OrderContext context) {
        System.out.println("订单已取消");
        context.setState(context.getCancelledState());
    }
    
    @Override
    public void ship(OrderContext context) {
        System.out.println("订单未确认,无法发货");
    }
    
    @Override
    public void deliver(OrderContext context) {
        System.out.println("订单未发货,无法交付");
    }
}

// 具体状态:已确认状态
public class ConfirmedState implements OrderState {
    @Override
    public void confirm(OrderContext context) {
        System.out.println("订单已确认,无需重复操作");
    }
    
    @Override
    public void cancel(OrderContext context) {
        System.out.println("订单已取消");
        context.setState(context.getCancelledState());
    }
    
    @Override
    public void ship(OrderContext context) {
        System.out.println("订单已发货");
        context.setState(context.getShippedState());
    }
    
    @Override
    public void deliver(OrderContext context) {
        System.out.println("订单未发货,无法交付");
    }
}

// 具体状态:已发货状态
public class ShippedState implements OrderState {
    @Override
    public void confirm(OrderContext context) {
        System.out.println("订单已发货,无法确认");
    }
    
    @Override
    public void cancel(OrderContext context) {
        System.out.println("订单已发货,无法取消");
    }
    
    @Override
    public void ship(OrderContext context) {
        System.out.println("订单已发货,无需重复操作");
    }
    
    @Override
    public void deliver(OrderContext context) {
        System.out.println("订单已交付");
        context.setState(context.getDeliveredState());
    }
}

// 具体状态:已交付状态
public class DeliveredState implements OrderState {
    @Override
    public void confirm(OrderContext context) {
        System.out.println("订单已完成,无法确认");
    }
    
    @Override
    public void cancel(OrderContext context) {
        System.out.println("订单已完成,无法取消");
    }
    
    @Override
    public void ship(OrderContext context) {
        System.out.println("订单已完成,无法发货");
    }
    
    @Override
    public void deliver(OrderContext context) {
        System.out.println("订单已完成,无需重复交付");
    }
}

// 具体状态:已取消状态
public class CancelledState implements OrderState {
    @Override
    public void confirm(OrderContext context) {
        System.out.println("订单已取消,无法确认");
    }
    
    @Override
    public void cancel(OrderContext context) {
        System.out.println("订单已取消,无需重复操作");
    }
    
    @Override
    public void ship(OrderContext context) {
        System.out.println("订单已取消,无法发货");
    }
    
    @Override
    public void deliver(OrderContext context) {
        System.out.println("订单已取消,无法交付");
    }
}

// 上下文:订单
public class OrderContext {
    private OrderState newState;
    private OrderState confirmedState;
    private OrderState shippedState;
    private OrderState deliveredState;
    private OrderState cancelledState;
    private OrderState currentState;
    
    public OrderContext() {
        newState = new NewState();
        confirmedState = new ConfirmedState();
        shippedState = new ShippedState();
        deliveredState = new DeliveredState();
        cancelledState = new CancelledState();
        currentState = newState; // 初始状态为新建
    }
    
    public void setState(OrderState state) {
        this.currentState = state;
    }
    
    // 委托操作到当前状态
    public void confirm() {
        currentState.confirm(this);
    }
    
    public void cancel() {
        currentState.cancel(this);
    }
    
    public void ship() {
        currentState.ship(this);
    }
    
    public void deliver() {
        currentState.deliver(this);
    }
    
    // 状态获取方法
    public OrderState getNewState() {
        return newState;
    }
    
    public OrderState getConfirmedState() {
        return confirmedState;
    }
    
    public OrderState getShippedState() {
        return shippedState;
    }
    
    public OrderState getDeliveredState() {
        return deliveredState;
    }
    
    public OrderState getCancelledState() {
        return cancelledState;
    }
}

// 使用示例
public class OrderDemo {
    public static void main(String[] args) {
        OrderContext order = new OrderContext();
        
        order.confirm(); // 确认
        order.ship();    // 发货
        order.deliver(); // 交付
        
        System.out.println("\n--- 取消场景 ---");
        OrderContext cancelledOrder = new OrderContext();
        cancelledOrder.confirm(); // 确认
        cancelledOrder.cancel();  // 取消
        cancelledOrder.ship();    // 尝试发货(失败)
    }
}

优缺点

优点:

  1. 状态转换显式化
  2. 消除条件分支语句
  3. 状态行为局部化
  4. 遵循开闭原则
  5. 状态对象可复用
  6. 提高可维护性

缺点:

  1. 状态类数量增加
  2. 上下文与状态耦合
  3. 状态转换逻辑可能复杂
  4. 状态共享困难
  5. 增加系统复杂度
  6. 性能开销(状态对象创建)

应用场景

  1. 工作流引擎
  2. 游戏角色状态
  3. 订单处理系统
  4. 网络协议状态机
  5. UI 控件状态
  6. 电梯控制系统
  7. 交通信号灯系统
  8. 自动售货机

与其他模式的关系

  • 与策略模式:结构相似但目的不同(策略是算法选择,状态是行为随状态改变)
  • 与享元模式:共享无状态的状态对象
  • 与单例模式:状态对象可为单例
  • 与组合模式:实现层次状态机
  • 与备忘录模式:保存和恢复状态
  • 与责任链模式:状态可委托到其他状态

JDK 中的状态模式

  1. Java 线程状态(Thread.State)
  2. Java FSM 框架(State Machine)
  3. Java AWT 组件状态
  4. Java Servlet 生命周期
  5. Spring 状态机(Spring StateMachine)
  6. Java NIO 通道状态(SelectionKey)
  7. Java 连接器状态(ConnectorState)

注意事项

  1. 状态转换控制(由谁管理转换)
  2. 状态共享策略
  3. 状态对象无状态化
  4. 处理状态初始化
  5. 避免状态循环依赖
  6. 状态层次结构设计
  7. 状态持久化策略
  8. 支持状态历史跟踪

贡献者

The avatar of contributor named as AKAcxp AKAcxp

页面历史