Java案例怎么实现状态模式?

wen java案例 42

Java状态模式实现案例

状态模式(State Pattern)允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。

Java案例怎么实现状态模式?

基础案例:订单状态

// 订单状态接口
public interface OrderState {
    void process(OrderContext context);
    void cancel(OrderContext context);
    void pay(OrderContext context);
    String getStateName();
}
// 订单上下文
public class OrderContext {
    private OrderState currentState;
    private String orderId;
    public OrderContext(String orderId) {
        this.orderId = orderId;
        this.currentState = new NewOrderState(); // 初始状态为新建订单
    }
    public void process() {
        currentState.process(this);
    }
    public void cancel() {
        currentState.cancel(this);
    }
    public void pay() {
        currentState.pay(this);
    }
    public void setState(OrderState state) {
        System.out.println("订单 " + orderId + " 状态变更: " 
            + currentState.getStateName() + " -> " + state.getStateName());
        this.currentState = state;
    }
    public OrderState getState() {
        return currentState;
    }
}
// 新建订单状态
class NewOrderState implements OrderState {
    @Override
    public void process(OrderContext context) {
        System.out.println("订单已确认,进入处理流程");
        context.setState(new ProcessingOrderState());
    }
    @Override
    public void cancel(OrderContext context) {
        System.out.println("新建订单取消成功");
        context.setState(new CancelledOrderState());
    }
    @Override
    public void pay(OrderContext context) {
        System.out.println("新建订单支付成功");
        context.setState(new PaidOrderState());
    }
    @Override
    public String getStateName() {
        return "新建订单";
    }
}
// 处理中订单状态
class ProcessingOrderState implements OrderState {
    @Override
    public void process(OrderContext context) {
        System.out.println("订单正在处理中,不能重复处理");
    }
    @Override
    public void cancel(OrderContext context) {
        System.out.println("处理中的订单取消成功");
        context.setState(new CancelledOrderState());
    }
    @Override
    public void pay(OrderContext context) {
        System.out.println("订单已支付完成");
        context.setState(new PaidOrderState());
    }
    @Override
    public String getStateName() {
        return "处理中";
    }
}
// 已支付订单状态
class PaidOrderState implements OrderState {
    @Override
    public void process(OrderContext context) {
        System.out.println("已支付订单不能再次处理");
    }
    @Override
    public void cancel(OrderContext context) {
        System.out.println("已支付订单取消,开始退款流程");
        context.setState(new RefundProcessingState());
    }
    @Override
    public void pay(OrderContext context) {
        System.out.println("订单已支付,不能重复支付");
    }
    @Override
    public String getStateName() {
        return "已支付";
    }
}
// 取消订单状态
class CancelledOrderState implements OrderState {
    @Override
    public void process(OrderContext context) {
        System.out.println("已取消的订单不能处理");
    }
    @Override
    public void cancel(OrderContext context) {
        System.out.println("订单已经取消");
    }
    @Override
    public void pay(OrderContext context) {
        System.out.println("已取消的订单不能支付");
    }
    @Override
    public String getStateName() {
        return "已取消";
    }
}
// 退款处理中状态
class RefundProcessingState implements OrderState {
    @Override
    public void process(OrderContext context) {
        System.out.println("退款处理中的订单不能处理");
    }
    @Override
    public void cancel(OrderContext context) {
        System.out.println("退款处理中,不能取消");
    }
    @Override
    public void pay(OrderContext context) {
        System.out.println("退款处理中,不能支付");
    }
    @Override
    public String getStateName() {
        return "退款处理中";
    }
}
// 测试类
public class StatePatternDemo {
    public static void main(String[] args) {
        OrderContext order = new OrderContext("2024001");
        // 测试状态流转
        order.process();      // 新建 -> 处理中
        order.pay();         // 处理中 -> 已支付
        order.cancel();      // 已支付 -> 退款处理中
        // 测试无效操作
        order.process();     // 退款处理中,不能处理
    }
}

实际案例:电梯控制系统

// 电梯状态接口
interface ElevatorState {
    void openDoor(ElevatorContext context);
    void closeDoor(ElevatorContext context);
    void moveUp(ElevatorContext context);
    void moveDown(ElevatorContext context);
    void stop(ElevatorContext context);
    String getStateName();
}
// 电梯上下文
class ElevatorContext {
    private ElevatorState currentState;
    private int currentFloor;
    public ElevatorContext() {
        this.currentState = new IdleState();
        this.currentFloor = 1;
    }
    public void setState(ElevatorState state) {
        System.out.println("电梯状态变更: " + currentState.getStateName() 
            + " -> " + state.getStateName());
        this.currentState = state;
    }
    public ElevatorState getState() {
        return currentState;
    }
    public int getCurrentFloor() {
        return currentFloor;
    }
    public void setCurrentFloor(int floor) {
        this.currentFloor = floor;
    }
    public void openDoor() { currentState.openDoor(this); }
    public void closeDoor() { currentState.closeDoor(this); }
    public void moveUp() { currentState.moveUp(this); }
    public void moveDown() { currentState.moveDown(this); }
    public void stop() { currentState.stop(this); }
}
// 空闲状态
class IdleState implements ElevatorState {
    @Override
    public void openDoor(ElevatorContext context) {
        System.out.println("电梯门打开");
        context.setState(new DoorOpenState());
    }
    @Override
    public void closeDoor(ElevatorContext context) {
        System.out.println("电梯门已经关闭");
    }
    @Override
    public void moveUp(ElevatorContext context) {
        System.out.println("电梯开始上行");
        context.setState(new MovingUpState());
    }
    @Override
    public void moveDown(ElevatorContext context) {
        System.out.println("电梯开始下行");
        context.setState(new MovingDownState());
    }
    @Override
    public void stop(ElevatorContext context) {
        System.out.println("电梯已经停止");
    }
    @Override
    public String getStateName() {
        return "空闲";
    }
}
// 门打开状态
class DoorOpenState implements ElevatorState {
    @Override
    public void openDoor(ElevatorContext context) {
        System.out.println("门已经打开");
    }
    @Override
    public void closeDoor(ElevatorContext context) {
        System.out.println("电梯门关闭");
        context.setState(new IdleState());
    }
    @Override
    public void moveUp(ElevatorContext context) {
        System.out.println("门未关闭,不能移动");
    }
    @Override
    public void moveDown(ElevatorContext context) {
        System.out.println("门未关闭,不能移动");
    }
    @Override
    public void stop(ElevatorContext context) {
        System.out.println("门已打开,处于停止状态");
    }
    @Override
    public String getStateName() {
        return "门打开";
    }
}
// 上行状态
class MovingUpState implements ElevatorState {
    @Override
    public void openDoor(ElevatorContext context) {
        System.out.println("运行中不能开门");
    }
    @Override
    public void closeDoor(ElevatorContext context) {
        System.out.println("运行中门已关闭");
    }
    @Override
    public void moveUp(ElevatorContext context) {
        context.setCurrentFloor(context.getCurrentFloor() + 1);
        System.out.println("上行至 " + context.getCurrentFloor() + " 层");
    }
    @Override
    public void moveDown(ElevatorContext context) {
        System.out.println("正在上行,不能直接下行");
    }
    @Override
    public void stop(ElevatorContext context) {
        System.out.println("电梯停止");
        context.setState(new IdleState());
    }
    @Override
    public String getStateName() {
        return "上行中";
    }
}
// 下行状态
class MovingDownState implements ElevatorState {
    @Override
    public void openDoor(ElevatorContext context) {
        System.out.println("运行中不能开门");
    }
    @Override
    public void closeDoor(ElevatorContext context) {
        System.out.println("运行中门已关闭");
    }
    @Override
    public void moveUp(ElevatorContext context) {
        System.out.println("正在下行,不能直接上行");
    }
    @Override
    public void moveDown(ElevatorContext context) {
        context.setCurrentFloor(context.getCurrentFloor() - 1);
        System.out.println("下行至 " + context.getCurrentFloor() + " 层");
    }
    @Override
    public void stop(ElevatorContext context) {
        System.out.println("电梯停止");
        context.setState(new IdleState());
    }
    @Override
    public String getStateName() {
        return "下行中";
    }
}
// 测试类
public class ElevatorDemo {
    public static void main(String[] args) {
        ElevatorContext elevator = new ElevatorContext();
        // 测试电梯操作
        elevator.openDoor();     // 空闲 -> 门打开
        elevator.closeDoor();    // 门打开 -> 空闲
        elevator.moveUp();       // 空闲 -> 上行中
        elevator.moveUp();       // 继续上行
        elevator.stop();         // 上行中 -> 空闲
        elevator.openDoor();     // 空闲 -> 门打开
        elevator.moveUp();       // 门打开状态,不能移动
        elevator.closeDoor();    // 门打开 -> 空闲
    }
}

状态模式的优缺点

优点:

  • 单一职责原则:将与特定状态相关的代码组织到单独的类中
  • 开闭原则:增加新状态容易,无需修改现有状态类
  • 消除庞大的条件分支语句
  • 状态转换逻辑清晰,集中在状态类中

缺点:

  • 类数量增加,管理复杂
  • 状态转换逻辑分散在多个状态类中
  • 如果状态简单,使用状态模式可能过度设计

实际应用场景

  • 订单系统、审批流程
  • 游戏角色状态(待机、攻击、防御)
  • UI组件状态(可编辑、只读、禁用)
  • 网络连接状态
  • 音视频播放器状态

抱歉,评论功能暂时关闭!