状态设计模式全方位深度解析

3 阅读18分钟

一、核心概念

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

设计思想

  • 状态驱动行为:将对象的行为封装在不同的状态类中
  • 消除条件分支:用多态替换复杂的条件判断语句
  • 状态转换:在状态内部定义状态转换逻辑
  • 开闭原则:新增状态不影响现有代码

二、模式结构

类图示意

复制
┌─────────────────┐         ┌───────────────┐
│    Context      │────────▶│    State      │
│  (上下文)       │         │  (状态接口)   │
├─────────────────┤         ├───────────────┤
│ -state: State  │         │ +handle()     │
│ +setState()    │         └───────────────┘
│ +request()     │                 △
└─────────────────┘                 │
         │             ┌────────────┴────────────┐
         │             │                         │
         │    ┌─────────────────┐    ┌─────────────────┐
         │    │ ConcreteStateA  │    │ ConcreteStateB  │
         │    ├─────────────────┤    ├─────────────────┤
         └────│ +handle()       │    │ +handle()       │
              │ +transitionTo() │    │ +transitionTo() │
              └─────────────────┘    └─────────────────┘

核心角色

  1. Context (上下文)

    • 定义客户端感兴趣的接口
    • 维护一个ConcreteState子类的实例
    • 委托状态相关的行为给当前状态对象
  2. State (状态接口)

    • 定义一个接口,用于封装与Context的特定状态相关的行为
  3. ConcreteState (具体状态)

    • 实现与Context的一个状态相关的行为
    • 可触发状态转换

三、Java代码实现

基础实现示例

java
java
下载
复制
// 1. 状态接口
public interface OrderState {
    void handle(OrderContext context);
    String getStatusName();
    boolean canCancel();
    boolean canPay();
    boolean canShip();
}

// 2. 具体状态类
// 新建订单状态
public class NewOrderState implements OrderState {
    @Override
    public void handle(OrderContext context) {
        System.out.println("订单已创建,等待付款");
    }
    
    @Override
    public String getStatusName() {
        return "新建";
    }
    
    @Override
    public boolean canCancel() {
        return true;  // 新建订单可以取消
    }
    
    @Override
    public boolean canPay() {
        return true;  // 新建订单可以支付
    }
    
    @Override
    public boolean canShip() {
        return false; // 新建订单不能发货
    }
    
    @Override
    public String toString() {
        return "新建订单状态";
    }
}

// 已支付状态
public class PaidState implements OrderState {
    @Override
    public void handle(OrderContext context) {
        System.out.println("订单已支付,等待发货");
    }
    
    @Override
    public String getStatusName() {
        return "已支付";
    }
    
    @Override
    public boolean canCancel() {
        return true;  // 已支付订单可以取消(但可能涉及退款)
    }
    
    @Override
    public boolean canPay() {
        return false; // 已支付订单不能再次支付
    }
    
    @Override
    public boolean canShip() {
        return true;  // 已支付订单可以发货
    }
    
    @Override
    public String toString() {
        return "已支付状态";
    }
}

// 已发货状态
public class ShippedState implements OrderState {
    @Override
    public void handle(OrderContext context) {
        System.out.println("订单已发货,运输中");
    }
    
    @Override
    public String getStatusName() {
        return "已发货";
    }
    
    @Override
    public boolean canCancel() {
        return false; // 已发货订单不能取消
    }
    
    @Override
    public boolean canPay() {
        return false; // 已发货订单不能支付
    }
    
    @Override
    public boolean canShip() {
        return false; // 已发货订单不能再次发货
    }
    
    @Override
    public String toString() {
        return "已发货状态";
    }
}

// 已完成状态
public class CompletedState implements OrderState {
    @Override
    public void handle(OrderContext context) {
        System.out.println("订单已完成,感谢购买");
    }
    
    @Override
    public String getStatusName() {
        return "已完成";
    }
    
    @Override
    public boolean canCancel() {
        return false; // 已完成订单不能取消
    }
    
    @Override
    public boolean canPay() {
        return false; // 已完成订单不能支付
    }
    
    @Override
    public boolean canShip() {
        return false; // 已完成订单不能发货
    }
    
    @Override
    public String toString() {
        return "已完成状态";
    }
}

// 已取消状态
public class CanceledState implements OrderState {
    @Override
    public void handle(OrderContext context) {
        System.out.println("订单已取消");
    }
    
    @Override
    public String getStatusName() {
        return "已取消";
    }
    
    @Override
    public boolean canCancel() {
        return false; // 已取消订单不能再次取消
    }
    
    @Override
    public boolean canPay() {
        return false; // 已取消订单不能支付
    }
    
    @Override
    public boolean canShip() {
        return false; // 已取消订单不能发货
    }
    
    @Override
    public String toString() {
        return "已取消状态";
    }
}

// 3. 上下文类
public class OrderContext {
    private OrderState currentState;
    private String orderId;
    private List<String> stateHistory = new ArrayList<>();
    
    public OrderContext(String orderId) {
        this.orderId = orderId;
        // 初始状态为新建
        this.currentState = new NewOrderState();
        this.stateHistory.add("订单创建 -> " + currentState.getStatusName());
        currentState.handle(this);
    }
    
    public void setState(OrderState state) {
        System.out.printf("订单状态变更: [%s] -> [%s]%n", 
            currentState.getStatusName(), state.getStatusName());
        
        this.currentState = state;
        this.stateHistory.add(state.getStatusName());
        this.currentState.handle(this);
    }
    
    public void pay() {
        if (currentState.canPay()) {
            System.out.println("执行支付操作...");
            // 模拟支付处理
            setState(new PaidState());
        } else {
            System.out.println("当前状态[" + currentState.getStatusName() + "]不允许支付");
        }
    }
    
    public void cancel() {
        if (currentState.canCancel()) {
            System.out.println("执行取消操作...");
            // 模拟取消处理
            setState(new CanceledState());
        } else {
            System.out.println("当前状态[" + currentState.getStatusName() + "]不允许取消");
        }
    }
    
    public void ship() {
        if (currentState.canShip()) {
            System.out.println("执行发货操作...");
            // 模拟发货处理
            setState(new ShippedState());
        } else {
            System.out.println("当前状态[" + currentState.getStatusName() + "]不允许发货");
        }
    }
    
    public void complete() {
        if (currentState instanceof ShippedState) {
            System.out.println("确认收货,订单完成...");
            setState(new CompletedState());
        } else {
            System.out.println("当前状态[" + currentState.getStatusName() + "]不能完成");
        }
    }
    
    public void returnGoods() {
        if (currentState instanceof ShippedState || currentState instanceof CompletedState) {
            System.out.println("申请退货...");
            // 退货流程
            setState(new CanceledState());
        } else {
            System.out.println("当前状态[" + currentState.getStatusName() + "]不能退货");
        }
    }
    
    // 状态查询方法
    public String getCurrentStatus() {
        return currentState.getStatusName();
    }
    
    public OrderState getCurrentState() {
        return currentState;
    }
    
    public List<String> getStateHistory() {
        return new ArrayList<>(stateHistory);
    }
    
    public String getOrderId() {
        return orderId;
    }
}

// 4. 状态转换规则(可选,用于管理状态转换逻辑)
public class StateTransitionRules {
    private Map<Class<? extends OrderState>, Map<String, Class<? extends OrderState>>> rules = new HashMap<>();
    
    public StateTransitionRules() {
        initializeRules();
    }
    
    private void initializeRules() {
        // 定义状态转换规则
        addRule(NewOrderState.class, "pay", PaidState.class);
        addRule(NewOrderState.class, "cancel", CanceledState.class);
        
        addRule(PaidState.class, "ship", ShippedState.class);
        addRule(PaidState.class, "cancel", CanceledState.class);
        
        addRule(ShippedState.class, "complete", CompletedState.class);
        addRule(ShippedState.class, "return", CanceledState.class);
        
        addRule(CompletedState.class, "return", CanceledState.class);
    }
    
    private void addRule(Class<? extends OrderState> fromState, String action, 
                        Class<? extends OrderState> toState) {
        rules.computeIfAbsent(fromState, k -> new HashMap<>())
             .put(action, toState);
    }
    
    public Class<? extends OrderState> getNextState(Class<? extends OrderState> currentState, String action) {
        Map<String, Class<? extends OrderState>> stateRules = rules.get(currentState);
        if (stateRules != null) {
            return stateRules.get(action);
        }
        return null;
    }
    
    public boolean canTransition(Class<? extends OrderState> currentState, String action) {
        return getNextState(currentState, action) != null;
    }
}

// 5. 客户端使用
public class StatePatternDemo {
    public static void main(String[] args) {
        System.out.println("=== 状态模式演示 - 订单状态管理 ===\n");
        
        // 创建订单
        OrderContext order = new OrderContext("ORD001");
        System.out.println("订单ID: " + order.getOrderId());
        System.out.println("当前状态: " + order.getCurrentStatus());
        
        // 测试状态转换
        System.out.println("\n--- 测试正常流程 ---");
        order.pay();     // 新建 -> 已支付
        order.ship();    // 已支付 -> 已发货
        order.complete(); // 已发货 -> 已完成
        
        System.out.println("\n--- 测试非法操作 ---");
        order.pay();     // 已完成 -> 不能支付
        order.ship();    // 已完成 -> 不能发货
        
        System.out.println("\n--- 测试退货流程 ---");
        OrderContext returnOrder = new OrderContext("ORD002");
        returnOrder.pay();
        returnOrder.ship();
        returnOrder.returnGoods(); // 已发货 -> 已取消(退货)
        
        System.out.println("\n--- 状态历史 ---");
        System.out.println("订单ORD001状态历史:");
        for (String state : order.getStateHistory()) {
            System.out.println("  - " + state);
        }
        
        // 测试状态规则
        testStateTransitionRules();
    }
    
    private static void testStateTransitionRules() {
        System.out.println("\n=== 状态转换规则测试 ===");
        StateTransitionRules rules = new StateTransitionRules();
        
        // 验证规则
        System.out.println("新建订单可以支付: " + 
            rules.canTransition(NewOrderState.class, "pay"));
        
        System.out.println("已支付订单可以发货: " + 
            rules.canTransition(PaidState.class, "ship"));
        
        System.out.println("已完成订单可以退货: " + 
            rules.canTransition(CompletedState.class, "return"));
    }
}

高级示例:有限状态机(FSM)

java
java
下载
复制
// 1. 状态机接口
public interface StateMachine<S, E> {
    S getCurrentState();
    void fire(E event);
    void addTransition(S fromState, E event, S toState, Runnable action);
    void addTransition(S fromState, E event, S toState);
}

// 2. 状态机实现
public class FiniteStateMachine<S, E> implements StateMachine<S, E> {
    private S currentState;
    private final Map<S, Map<E, Transition<S, E>>> transitions = new HashMap<>();
    private final Set<S> states = new HashSet<>();
    private final Set<E> events = new HashSet<>();
    
    public FiniteStateMachine(S initialState) {
        this.currentState = initialState;
        states.add(initialState);
    }
    
    @Override
    public S getCurrentState() {
        return currentState;
    }
    
    @Override
    public void fire(E event) {
        Map<E, Transition<S, E>> stateTransitions = transitions.get(currentState);
        if (stateTransitions == null) {
            throw new IllegalStateException("No transitions defined for state: " + currentState);
        }
        
        Transition<S, E> transition = stateTransitions.get(event);
        if (transition == null) {
            throw new IllegalStateException("No transition defined for event: " + event + 
                                          " in state: " + currentState);
        }
        
        // 执行转换
        if (transition.getAction() != null) {
            transition.getAction().run();
        }
        
        S oldState = currentState;
        currentState = transition.getToState();
        
        System.out.printf("状态转换: [%s] --%s--> [%s]%n", 
            oldState, event, currentState);
    }
    
    @Override
    public void addTransition(S fromState, E event, S toState, Runnable action) {
        states.add(fromState);
        states.add(toState);
        events.add(event);
        
        transitions.computeIfAbsent(fromState, k -> new HashMap<>())
                  .put(event, new Transition<>(fromState, event, toState, action));
    }
    
    @Override
    public void addTransition(S fromState, E event, S toState) {
        addTransition(fromState, event, toState, null);
    }
    
    public boolean canFire(E event) {
        Map<E, Transition<S, E>> stateTransitions = transitions.get(currentState);
        return stateTransitions != null && stateTransitions.containsKey(event);
    }
    
    public Set<E> getAvailableEvents() {
        Map<E, Transition<S, E>> stateTransitions = transitions.get(currentState);
        if (stateTransitions == null) {
            return Collections.emptySet();
        }
        return stateTransitions.keySet();
    }
    
    // 转换类
    private static class Transition<S, E> {
        private final S fromState;
        private final E event;
        private final S toState;
        private final Runnable action;
        
        public Transition(S fromState, E event, S toState, Runnable action) {
            this.fromState = fromState;
            this.event = event;
            this.toState = toState;
            this.action = action;
        }
        
        public S getFromState() { return fromState; }
        public E getEvent() { return event; }
        public S getToState() { return toState; }
        public Runnable getAction() { return action; }
    }
}

// 3. 使用状态机的工作流示例
public class WorkflowStateMachine {
    public enum State {
        DRAFT, REVIEWING, APPROVED, REJECTED, PUBLISHED, ARCHIVED
    }
    
    public enum Event {
        SUBMIT, APPROVE, REJECT, PUBLISH, ARCHIVE, REOPEN
    }
    
    public static void main(String[] args) {
        // 创建状态机
        FiniteStateMachine<State, Event> fsm = new FiniteStateMachine<>(State.DRAFT);
        
        // 定义状态转换
        fsm.addTransition(State.DRAFT, Event.SUBMIT, State.REVIEWING, 
            () -> System.out.println("提交文档进入审核流程"));
        
        fsm.addTransition(State.REVIEWING, Event.APPROVE, State.APPROVED,
            () -> System.out.println("文档审核通过"));
        
        fsm.addTransition(State.REVIEWING, Event.REJECT, State.REJECTED,
            () -> System.out.println("文档审核驳回"));
        
        fsm.addTransition(State.APPROVED, Event.PUBLISH, State.PUBLISHED,
            () -> System.out.println("文档已发布"));
        
        fsm.addTransition(State.REJECTED, Event.REOPEN, State.DRAFT,
            () -> System.out.println("重新打开文档进行修改"));
        
        fsm.addTransition(State.PUBLISHED, Event.ARCHIVE, State.ARCHIVED,
            () -> System.out.println("文档已归档"));
        
        // 执行状态转换
        System.out.println("当前状态: " + fsm.getCurrentState());
        System.out.println("可用事件: " + fsm.getAvailableEvents());
        
        fsm.fire(Event.SUBMIT);
        System.out.println("当前状态: " + fsm.getCurrentState());
        System.out.println("可用事件: " + fsm.getAvailableEvents());
        
        fsm.fire(Event.APPROVE);
        System.out.println("当前状态: " + fsm.getCurrentState());
        System.out.println("可用事件: " + fsm.getAvailableEvents());
        
        fsm.fire(Event.PUBLISH);
        System.out.println("当前状态: " + fsm.getCurrentState());
        System.out.println("可用事件: " + fsm.getAvailableEvents());
        
        // 测试非法转换
        try {
            fsm.fire(Event.REJECT); // 应该失败
        } catch (IllegalStateException e) {
            System.out.println("预期错误: " + e.getMessage());
        }
    }
}

四、应用场景

1. 订单/工作流系统

java
java
下载
复制
// 复杂的订单状态机
public class ComplexOrderWorkflow {
    public enum OrderStateEnum {
        CREATED, VALIDATING, PAYMENT_PENDING, PAYMENT_PROCESSING,
        PAYMENT_FAILED, PAYMENT_COMPLETED, INVENTORY_CHECKING,
        INVENTORY_RESERVED, PACKING, SHIPPING, DELIVERED,
        CANCELLED, REFUND_PENDING, REFUNDED, COMPLETED
    }
    
    public class OrderStateMachine {
        private OrderStateEnum currentState;
        private String orderId;
        private StateTransitionValidator validator = new StateTransitionValidator();
        
        public void transition(OrderStateEnum newState, Map<String, Object> context) {
            if (validator.isValidTransition(currentState, newState, context)) {
                OrderStateEnum oldState = currentState;
                currentState = newState;
                executeStateActions(oldState, newState, context);
                logTransition(oldState, newState, context);
            } else {
                throw new IllegalStateException(
                    String.format("无效的状态转换: %s -> %s", currentState, newState));
            }
        }
        
        private void executeStateActions(OrderStateEnum from, OrderStateEnum to, 
                                        Map<String, Object> context) {
            // 执行进入状态的动作
            switch (to) {
                case PAYMENT_PROCESSING:
                    processPayment(context);
                    break;
                case INVENTORY_RESERVED:
                    reserveInventory(context);
                    break;
                case SHIPPING:
                    createShippingLabel(context);
                    break;
                case DELIVERED:
                    sendDeliveryNotification(context);
                    break;
                case REFUNDED:
                    processRefund(context);
                    break;
            }
            
            // 执行离开状态的动作
            switch (from) {
                case PAYMENT_PROCESSING:
                    cleanupPaymentSession(context);
                    break;
                case INVENTORY_RESERVED:
                    releaseTemporaryHold(context);
                    break;
            }
        }
    }
}

2. 游戏开发

java
java
下载
复制
// 游戏角色状态
public class GameCharacter {
    private CharacterState currentState;
    private int health = 100;
    private int mana = 50;
    
    public interface CharacterState {
        void handleInput(GameCharacter character, String input);
        void update(GameCharacter character);
        void enter(GameCharacter character);
        void exit(GameCharacter character);
        String getStateName();
    }
    
    public class IdleState implements CharacterState {
        @Override
        public void handleInput(GameCharacter character, String input) {
            switch (input) {
                case "WALK":
                    character.setState(new WalkingState());
                    break;
                case "ATTACK":
                    character.setState(new AttackingState());
                    break;
                case "CAST":
                    if (character.mana >= 10) {
                        character.setState(new CastingState());
                    }
                    break;
            }
        }
        
        @Override
        public void update(GameCharacter character) {
            // 缓慢恢复生命值和魔法值
            character.health = Math.min(100, character.health + 1);
            character.mana = Math.min(100, character.mana + 2);
        }
    }
    
    public class WalkingState implements CharacterState {
        @Override
        public void handleInput(GameCharacter character, String input) {
            if (input.equals("STOP")) {
                character.setState(new IdleState());
            }
        }
        
        @Override
        public void update(GameCharacter character) {
            // 移动逻辑
        }
    }
    
    public class AttackingState implements CharacterState {
        private int attackCooldown = 0;
        
        @Override
        public void handleInput(GameCharacter character, String input) {
            if (input.equals("STOP_ATTACK")) {
                character.setState(new IdleState());
            }
        }
        
        @Override
        public void update(GameCharacter character) {
            if (attackCooldown > 0) {
                attackCooldown--;
            } else {
                // 攻击逻辑
                attackCooldown = 20; // 20帧冷却
            }
        }
    }
}

3. 网络连接管理

java
java
下载
复制
// TCP连接状态机
public class TCPConnection {
    private TCPState state;
    private String remoteAddress;
    private int remotePort;
    
    public interface TCPState {
        void open(TCPConnection connection);
        void close(TCPConnection connection);
        void acknowledge(TCPConnection connection);
        void send(TCPConnection connection, byte[] data);
        TCPStateEnum getState();
    }
    
    public enum TCPStateEnum {
        CLOSED, LISTEN, SYN_SENT, SYN_RECEIVED,
        ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2,
        CLOSE_WAIT, CLOSING, LAST_ACK, TIME_WAIT
    }
    
    public class ClosedState implements TCPState {
        @Override
        public void open(TCPConnection connection) {
            System.out.println("发送SYN包");
            connection.setState(new SynSentState());
        }
        
        @Override
        public void close(TCPConnection connection) {
            // 已经是关闭状态
        }
        
        @Override
        public void acknowledge(TCPConnection connection) {
            throw new IllegalStateException("连接已关闭");
        }
        
        @Override
        public void send(TCPConnection connection, byte[] data) {
            throw new IllegalStateException("连接已关闭,不能发送数据");
        }
    }
    
    public class EstablishedState implements TCPState {
        @Override
        public void open(TCPConnection connection) {
            throw new IllegalStateException("连接已建立");
        }
        
        @Override
        public void close(TCPConnection connection) {
            System.out.println("发送FIN包");
            connection.setState(new FinWait1State());
        }
        
        @Override
        public void acknowledge(TCPConnection connection) {
            // 处理ACK
        }
        
        @Override
        public void send(TCPConnection connection, byte[] data) {
            System.out.println("发送数据: " + data.length + " bytes");
            // 实际发送逻辑
        }
    }
    
    // 其他状态实现...
    
    public void setState(TCPState state) {
        System.out.println("TCP连接状态变更: " + this.state + " -> " + state);
        this.state = state;
    }
    
    public void send(byte[] data) {
        state.send(this, data);
    }
}

4. UI组件状态

java
java
下载
复制
// 按钮状态管理
public class UIButton {
    private ButtonState state;
    private String text;
    private boolean enabled = true;
    private Runnable onClick;
    
    public interface ButtonState {
        void render(UIButton button, Graphics2D g);
        void handleClick(UIButton button, MouseEvent e);
        void handleHover(UIButton button, MouseEvent e);
        void handleLeave(UIButton button, MouseEvent e);
        void setEnabled(UIButton button, boolean enabled);
    }
    
    public class NormalState implements ButtonState {
        @Override
        public void render(UIButton button, Graphics2D g) {
            g.setColor(Color.BLUE);
            g.fillRect(0, 0, button.getWidth(), button.getHeight());
            g.setColor(Color.WHITE);
            g.drawString(button.text, 10, 20);
        }
        
        @Override
        public void handleClick(UIButton button, MouseEvent e) {
            if (button.onClick != null && button.enabled) {
                button.setState(new ClickedState());
                button.onClick.run();
            }
        }
        
        @Override
        public void handleHover(UIButton button, MouseEvent e) {
            button.setState(new HoverState());
        }
    }
    
    public class HoverState implements ButtonState {
        @Override
        public void render(UIButton button, Graphics2D g) {
            g.setColor(Color.CYAN);
            g.fillRect(0, 0, button.getWidth(), button.getHeight());
            g.setColor(Color.WHITE);
            g.drawString(button.text, 10, 20);
        }
    }
    
    public class ClickedState implements ButtonState {
        @Override
        public void render(UIButton button, Graphics2D g) {
            g.setColor(Color.DARK_GRAY);
            g.fillRect(0, 0, button.getWidth(), button.getHeight());
            g.setColor(Color.WHITE);
            g.drawString(button.text, 10, 20);
        }
        
        @Override
        public void handleLeave(UIButton button, MouseEvent e) {
            button.setState(new NormalState());
        }
    }
    
    public class DisabledState implements ButtonState {
        @Override
        public void render(UIButton button, Graphics2D g) {
            g.setColor(Color.GRAY);
            g.fillRect(0, 0, button.getWidth(), button.getHeight());
            g.setColor(Color.LIGHT_GRAY);
            g.drawString(button.text, 10, 20);
        }
        
        @Override
        public void setEnabled(UIButton button, boolean enabled) {
            if (enabled) {
                button.setState(new NormalState());
            }
        }
    }
}

五、优缺点分析

优点

  1. 单一职责原则:每个状态类负责特定状态的行为
  2. 开闭原则:新增状态无需修改现有代码
  3. 消除条件分支:用多态替代复杂的条件语句
  4. 状态转换明确:状态转换逻辑集中管理
  5. 提高可维护性:状态逻辑分离,易于理解和维护
  6. 便于测试:每个状态可以独立测试
  7. 状态局部化:状态相关行为封装在状态类中

缺点

  1. 类数量增加:每个状态需要一个类,可能产生大量小类
  2. 复杂度增加:简单状态机可能过度设计
  3. 状态共享困难:状态间共享数据较复杂
  4. 上下文依赖:状态类通常需要了解上下文
  5. 性能开销:多态调用比条件判断稍慢
  6. 状态爆炸:状态数量多时难以管理

六、改进与变体

1. 表驱动状态机

java
java
下载
复制
// 使用表驱动的方式实现状态机
public class TableDrivenStateMachine<S, E> {
    private S currentState;
    private final Map<S, Map<E, Transition<S>>> transitionTable = new HashMap<>();
    private final Map<S, Runnable> entryActions = new HashMap<>();
    private final Map<S, Runnable> exitActions = new HashMap<>();
    private final Map<TransitionKey<S, E>, Runnable> transitionActions = new HashMap<>();
    
    public void addTransition(S from, E event, S to) {
        transitionTable.computeIfAbsent(from, k -> new HashMap<>())
                      .put(event, to);
    }
    
    public void addTransition(S from, E event, S to, Runnable action) {
        addTransition(from, event, to);
        transitionActions.put(new TransitionKey<>(from, event), action);
    }
    
    public void onEntry(S state, Runnable action) {
        entryActions.put(state, action);
    }
    
    public void onExit(S state, Runnable action) {
        exitActions.put(state, action);
    }
    
    public void fire(E event) {
        Map<E, Transition<S>> stateTransitions = transitionTable.get(currentState);
        if (stateTransitions == null) {
            throw new IllegalStateException("No transitions from state: " + currentState);
        }
        
        S toState = stateTransitions.get(event);
        if (toState == null) {
            throw new IllegalStateException("No transition for event: " + event);
        }
        
        // 执行退出动作
        Runnable exitAction = exitActions.get(currentState);
        if (exitAction != null) {
            exitAction.run();
        }
        
        // 执行转换动作
        Runnable transitionAction = transitionActions.get(new TransitionKey<>(currentState, event));
        if (transitionAction != null) {
            transitionAction.run();
        }
        
        S fromState = currentState;
        currentState = toState;
        
        // 执行进入动作
        Runnable entryAction = entryActions.get(currentState);
        if (entryAction != null) {
            entryAction.run();
        }
        
        System.out.printf("状态转换: %s --%s--> %s%n", fromState, event, currentState);
    }
    
    private static class TransitionKey<S, E> {
        private final S from;
        private final E event;
        
        public TransitionKey(S from, E event) {
            this.from = from;
            this.event = event;
        }
        
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            TransitionKey<?, ?> that = (TransitionKey<?, ?>) o;
            return Objects.equals(from, that.from) && Objects.equals(event, that.event);
        }
        
        @Override
        public int hashCode() {
            return Objects.hash(from, event);
        }
    }
    
    private static class Transition<S> {
        private final S toState;
        
        public Transition(S toState) {
            this.toState = toState;
        }
        
        public S getToState() {
            return toState;
        }
    }
}

2. 状态模式 + 享元模式

java
java
下载
复制
// 使用享元模式共享状态对象
public class StateFlyweightFactory {
    private static final Map<String, OrderState> statePool = new ConcurrentHashMap<>();
    
    static {
        // 预加载所有状态
        statePool.put("NEW", new NewOrderState());
        statePool.put("PAID", new PaidState());
        statePool.put("SHIPPED", new ShippedState());
        statePool.put("COMPLETED", new CompletedState());
        statePool.put("CANCELED", new CanceledState());
    }
    
    public static OrderState getState(String stateKey) {
        OrderState state = statePool.get(stateKey);
        if (state == null) {
            throw new IllegalArgumentException("未知状态: " + stateKey);
        }
        return state;
    }
    
    public static void registerState(String stateKey, OrderState state) {
        statePool.put(stateKey, state);
    }
}

// 修改后的上下文
public class FlyweightOrderContext {
    private OrderState currentState;
    private String orderId;
    
    public FlyweightOrderContext(String orderId, String initialState) {
        this.orderId = orderId;
        this.currentState = StateFlyweightFactory.getState(initialState);
    }
    
    public void transitionTo(String newStateKey) {
        OrderState newState = StateFlyweightFactory.getState(newStateKey);
        System.out.printf("订单 %s: %s -> %s%n", 
            orderId, currentState.getStatusName(), newState.getStatusName());
        this.currentState = newState;
    }
}

3. 状态模式 + 策略模式

java
java
下载
复制
// 结合策略模式,状态可以动态替换策略
public interface ProcessingStrategy {
    void process(Order order);
    boolean canExecute(Order order);
    String getStrategyName();
}

public class StateDrivenProcessor {
    private OrderState currentState;
    private ProcessingStrategy currentStrategy;
    private Map<Class<? extends OrderState>, ProcessingStrategy> strategyMap = new HashMap<>();
    
    public StateDrivenProcessor() {
        // 初始化状态-策略映射
        strategyMap.put(NewOrderState.class, new ValidationStrategy());
        strategyMap.put(PaidState.class, new PaymentVerificationStrategy());
        strategyMap.put(ShippedState.class, new ShippingStrategy());
        strategyMap.put(CompletedState.class, new CompletionStrategy());
        
        // 初始状态
        setState(new NewOrderState());
    }
    
    public void setState(OrderState state) {
        this.currentState = state;
        this.currentStrategy = strategyMap.get(state.getClass());
        if (currentStrategy == null) {
            throw new IllegalArgumentException("没有找到对应的处理策略: " + state.getClass());
        }
    }
    
    public void processOrder(Order order) {
        if (currentStrategy.canExecute(order)) {
            currentStrategy.process(order);
        } else {
            System.out.println("当前状态不支持此处理策略");
        }
    }
}

4. 可配置状态机

java
java
下载
复制
// 从配置文件加载状态机定义
public class ConfigurableStateMachine {
    private String currentState;
    private final Map<String, StateDefinition> stateDefinitions = new HashMap<>();
    private final ObjectMapper objectMapper = new ObjectMapper();
    
    public static class StateDefinition {
        private String name;
        private Map<String, String> transitions = new HashMap<>();
        private List<String> entryActions = new ArrayList<>();
        private List<String> exitActions = new ArrayList<>();
        private Map<String, String> conditions = new HashMap<>();
        
        // getters and setters
    }
    
    public void loadFromJson(String jsonConfig) throws IOException {
        StateDefinition[] states = objectMapper.readValue(jsonConfig, StateDefinition[].class);
        for (StateDefinition state : states) {
            stateDefinitions.put(state.getName(), state);
        }
        
        // 设置初始状态
        if (!stateDefinitions.isEmpty()) {
            currentState = states[0].getName();
        }
    }
    
    public boolean fire(String event, Map<String, Object> context) {
        StateDefinition currentStateDef = stateDefinitions.get(currentState);
        if (currentStateDef == null) {
            return false;
        }
        
        String nextState = currentStateDef.getTransitions().get(event);
        if (nextState == null) {
            return false;
        }
        
        // 检查条件
        String condition = currentStateDef.getConditions().get(event);
        if (condition != null && !evaluateCondition(condition, context)) {
            return false;
        }
        
        // 执行退出动作
        executeActions(currentStateDef.getExitActions(), context);
        
        // 状态转换
        String oldState = currentState;
        currentState = nextState;
        
        // 执行进入动作
        StateDefinition newStateDef = stateDefinitions.get(currentState);
        executeActions(newStateDef.getEntryActions(), context);
        
        System.out.printf("状态转换: %s --%s--> %s%n", oldState, event, currentState);
        return true;
    }
    
    private boolean evaluateCondition(String condition, Map<String, Object> context) {
        // 简单的条件表达式求值
        // 实际实现可以使用表达式引擎如MVEL、SpEL等
        return true; // 简化实现
    }
    
    private void executeActions(List<String> actions, Map<String, Object> context) {
        for (String action : actions) {
            System.out.println("执行动作: " + action);
            // 实际执行动作逻辑
        }
    }
}

七、注意事项

1. 状态对象管理

java
java
下载
复制
// 状态对象生命周期管理
public class StateLifecycleManager {
    private Map<Class<? extends State>, State> stateInstances = new HashMap<>();
    private boolean useSingletonStates = true;
    
    public State getState(Class<? extends State> stateClass) {
        if (useSingletonStates) {
            // 使用单例状态对象
            return stateInstances.computeIfAbsent(stateClass, this::createState);
        } else {
            // 每次都创建新实例
            return createState(stateClass);
        }
    }
    
    private State createState(Class<? extends State> stateClass) {
        try {
            return stateClass.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new RuntimeException("创建状态实例失败: " + stateClass.getName(), e);
        }
    }
    
    public void cleanup() {
        // 清理状态对象
        for (State state : stateInstances.values()) {
            if (state instanceof Disposable) {
                ((Disposable) state).dispose();
            }
        }
        stateInstances.clear();
    }
    
    public interface Disposable {
        void dispose();
    }
}

2. 线程安全实现

java
java
下载
复制
// 线程安全的状态上下文
public class ThreadSafeStateContext<S extends State> {
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    private S currentState;
    private final StateValidator<S> validator;
    private final List<StateChangeListener<S>> listeners = new CopyOnWriteArrayList<>();
    
    public ThreadSafeStateContext(S initialState, StateValidator<S> validator) {
        this.currentState = initialState;
        this.validator = validator;
    }
    
    public void transitionTo(S newState, Object... args) {
        lock.writeLock().lock();
        try {
            // 验证状态转换
            if (!validator.isValidTransition(currentState, newState, args)) {
                throw new IllegalStateException(
                    String.format("无效的状态转换: %s -> %s", 
                    currentState.getClass().getSimpleName(), 
                    newState.getClass().getSimpleName()));
            }
            
            S oldState = currentState;
            
            // 执行退出动作
            oldState.onExit(this, args);
            
            // 状态转换
            currentState = newState;
            
            // 执行进入动作
            newState.onEnter(this, args);
            
            // 通知监听器
            notifyStateChange(oldState, newState, args);
            
        } finally {
            lock.writeLock().unlock();
        }
    }
    
    public void handleEvent(Event event) {
        lock.readLock().lock();
        try {
            currentState.handleEvent(this, event);
        } finally {
            lock.readLock().unlock();
        }
    }
    
    public S getCurrentState() {
        lock.readLock().lock();
        try {
            return currentState;
        } finally {
            lock.readLock().unlock();
        }
    }
    
    private void notifyStateChange(S oldState, S newState, Object... args) {
        for (StateChangeListener<S> listener : listeners) {
            listener.onStateChanged(oldState, newState, args);
        }
    }
    
    public void addStateChangeListener(StateChangeListener<S> listener) {
        listeners.add(listener);
    }
    
    public interface StateValidator<S> {
        boolean isValidTransition(S fromState, S toState, Object... args);
    }
    
    public interface StateChangeListener<S> {
        void onStateChanged(S oldState, S newState, Object... args);
    }
}

3. 状态持久化

java
java
下载
复制
// 状态持久化支持
public class PersistentStateContext<S extends Serializable> {
    private S currentState;
    private final StatePersistence<S> persistence;
    private final String contextId;
    
    public PersistentStateContext(String contextId, S initialState, 
                                 StatePersistence<S> persistence) {
        this.contextId = contextId;
        this.persistence = persistence;
        
        // 尝试从持久化存储加载状态
        S savedState = persistence.loadState(contextId);
        this.currentState = (savedState != null) ? savedState : initialState;
    }
    
    public synchronized void transitionTo(S newState, boolean persist) {
        S oldState = currentState;
        currentState = newState;
        
        if (persist) {
            persistence.saveState(contextId, newState);
        }
        
        // 记录状态转换日志
        persistence.logTransition(contextId, oldState, newState);
    }
    
    public S getCurrentState() {
        return currentState;
    }
    
    public List<StateTransition<S>> getTransitionHistory() {
        return persistence.getTransitionHistory(contextId);
    }
    
    public interface StatePersistence<S> {
        void saveState(String contextId, S state);
        S loadState(String contextId);
        void logTransition(String contextId, S fromState, S toState);
        List<StateTransition<S>> getTransitionHistory(String contextId);
    }
    
    public static class StateTransition<S> {
        private final S fromState;
        private final S toState;
        private final Date timestamp;
        
        public StateTransition(S fromState, S toState) {
            this.fromState = fromState;
            this.toState = toState;
            this.timestamp = new Date();
        }
    }
}

4. 状态模式与枚举结合

java
java
下载
复制
// 使用枚举实现简单状态机
public enum OrderStatus {
    NEW {
        @Override
        public boolean canTransitionTo(OrderStatus next) {
            return next == PAID || next == CANCELLED;
        }
        
        @Override
        public void onEnter(Order order) {
            order.setCreatedTime(new Date());
            System.out.println("新订单创建");
        }
    },
    
    PAID {
        @Override
        public boolean canTransitionTo(OrderStatus next) {
            return next == SHIPPED || next == CANCELLED;
        }
        
        @Override
        public void onEnter(Order order) {
            order.setPaidTime(new Date());
            System.out.println("订单已支付");
        }
    },
    
    SHIPPED {
        @Override
        public boolean canTransitionTo(OrderStatus next) {
            return next == DELIVERED || next == CANCELLED;
        }
        
        @Override
        public void onEnter(Order order) {
            order.setShippedTime(new Date());
            System.out.println("订单已发货");
        }
    },
    
    DELIVERED {
        @Override
        public boolean canTransitionTo(OrderStatus next) {
            return next == COMPLETED;
        }
        
        @Override
        public void onEnter(Order order) {
            order.setDeliveredTime(new Date());
            System.out.println("订单已送达");
        }
    },
    
    COMPLETED {
        @Override
        public boolean canTransitionTo(OrderStatus next) {
            return false; // 最终状态
        }
    },
    
    CANCELLED {
        @Override
        public boolean canTransitionTo(OrderStatus next) {
            return false; // 最终状态
        }
        
        @Override
        public void onEnter(Order order) {
            order.setCancelledTime(new Date());
            System.out.println("订单已取消");
        }
    };
    
    public abstract boolean canTransitionTo(OrderStatus next);
    
    public void onEnter(Order order) {
        // 默认空实现
    }
    
    public void onExit(Order order) {
        // 默认空实现
    }
    
    // 状态转换方法
    public OrderStatus transitionTo(OrderStatus next, Order order) {
        if (!canTransitionTo(next)) {
            throw new IllegalStateException(
                String.format("不能从状态 %s 转换到 %s", this, next));
        }
        
        this.onExit(order);
        OrderStatus oldStatus = order.getStatus();
        order.setStatus(next);
        next.onEnter(order);
        
        return oldStatus;
    }
}

八、与其他模式的关系

1. 状态模式 vs 策略模式

java
java
下载
复制
// 状态模式:行为随状态改变,状态知道其他状态的存在
// 策略模式:算法可互换,策略之间相互独立

// 状态模式示例
public class StatePatternDemo {
    public static void main(String[] args) {
        OrderContext order = new OrderContext("ORD001");
        order.pay();    // 状态自动转换
        order.ship();   // 状态自动转换
    }
}

// 策略模式示例
public class StrategyPatternDemo {
    public static void main(String[] args) {
        PaymentProcessor processor = new PaymentProcessor();
        processor.setStrategy(new CreditCardStrategy());
        processor.process(100.0);  // 使用信用卡
        
        processor.setStrategy(new PayPalStrategy());
        processor.process(200.0);  // 使用PayPal
    }
}

2. 状态模式 + 观察者模式

java
java
下载
复制
// 状态变化通知观察者
public class ObservableStateContext {
    private State currentState;
    private List<StateObserver> observers = new ArrayList<>();
    
    public void setState(State newState) {
        State oldState = this.currentState;
        this.currentState = newState;
        
        // 通知观察者
        for (StateObserver observer : observers) {
            observer.onStateChanged(oldState, newState);
        }
    }
    
    public void addObserver(StateObserver observer) {
        observers.add(observer);
    }
    
    public interface StateObserver {
        void onStateChanged(State oldState, State newState);
    }
}

3. 状态模式 + 访问者模式

java
java
下载
复制
// 访问者处理不同状态
public interface StateVisitor {
    void visit(NewOrderState state);
    void visit(PaidState state);
    void visit(ShippedState state);
    void visit(CompletedState state);
    void visit(CanceledState state);
}

public abstract class OrderState {
    public abstract void accept(StateVisitor visitor);
    // 其他方法...
}

public class NewOrderState extends OrderState {
    @Override
    public void accept(StateVisitor visitor) {
        visitor.visit(this);
    }
}

// 具体访问者
public class StateStatisticsVisitor implements StateVisitor {
    private Map<Class<? extends OrderState>, Integer> statistics = new HashMap<>();
    
    @Override
    public void visit(NewOrderState state) {
        statistics.merge(NewOrderState.class, 1, Integer::sum);
    }
    
    @Override
    public void visit(PaidState state) {
        statistics.merge(PaidState.class, 1, Integer::sum);
    }
    
    // 实现其他visit方法...
    
    public Map<Class<? extends OrderState>, Integer> getStatistics() {
        return new HashMap<>(statistics);
    }
}

九、实际应用建议

适用场景判断

适合使用状态模式的场景:

  1. 对象的行为依赖于它的状态,并且必须在运行时根据状态改变行为
  2. 操作中有大量条件语句,且这些条件依赖于对象的状态
  3. 状态转换逻辑复杂,需要清晰的管理
  4. 状态数量较多,且可能频繁增加
  5. 需要实现状态机或工作流引擎

不适合的场景:

  1. 状态数量很少(2-3个)且稳定
  2. 状态转换逻辑简单,用条件判断足够清晰
  3. 对性能要求极高,需要避免多态调用开销
  4. 状态之间没有明显的行为差异

最佳实践

  1. 明确状态转换:在状态类中定义转换逻辑
  2. 使用享元模式:共享无状态的状态对象
  3. 考虑线程安全:多线程环境需要同步
  4. 添加状态验证:验证状态转换的合法性
  5. 提供状态历史:记录状态转换轨迹
  6. 实现状态持久化:支持状态恢复
  7. 使用生成器模式:简化状态机构建
  8. 添加监控和日志:便于调试和监控

性能优化策略

java
java
下载
复制
// 状态机优化
public class OptimizedStateMachine {
    // 1. 使用枚举代替类
    public enum OptimizedState {
        STATE_A, STATE_B, STATE_C;
        
        private static final Map<OptimizedState, Map<String, OptimizedState>> transitions = 
            new EnumMap<>(OptimizedState.class);
        
        static {
            // 初始化状态转换表
            transitions.put(STATE_A, Map.of("event1", STATE_B, "event2", STATE_C));
            transitions.put(STATE_B, Map.of("event3", STATE_C));
            transitions.put(STATE_C, Collections.emptyMap());
        }
        
        public OptimizedState transition(String event) {
            Map<String, OptimizedState> stateTransitions = transitions.get(this);
            if (stateTransitions != null) {
                OptimizedState nextState = stateTransitions.get(event);
                if (nextState != null) {
                    return nextState;
                }
            }
            throw new IllegalStateException("无效的事件: " + event + " 对于状态: " + this);
        }
    }
    
    // 2. 使用数组提高性能
    public class ArrayBasedStateMachine {
        private int currentState;
        private final int[][] transitionTable;
        private final Runnable[][] actionTable;
        
        public ArrayBasedStateMachine(int stateCount, int eventCount) {
            transitionTable = new int[stateCount][eventCount];
            actionTable = new Runnable[stateCount][eventCount];
            
            // 初始化所有转换为无效状态(-1)
            for (int i = 0; i < stateCount; i++) {
                Arrays.fill(transitionTable[i], -1);
            }
        }
        
        public void addTransition(int fromState, int event, int toState, Runnable action) {
            transitionTable[fromState][event] = toState;
            actionTable[fromState][event] = action;
        }
        
        public boolean fire(int event) {
            int nextState = transitionTable[currentState][event];
            if (nextState == -1) {
                return false;
            }
            
            Runnable action = actionTable[currentState][event];
            if (action != null) {
                action.run();
            }
            
            currentState = nextState;
            return true;
        }
    }
}

十、总结

状态模式是处理对象状态驱动行为的强大工具,特别适合状态转换复杂、行为随状态变化的系统。正确使用时,它能显著提高代码的可维护性和扩展性。

关键要点:

  1. 将每种状态封装为独立的类
  2. 状态转换逻辑可以在上下文或状态类中
  3. 使用多态替代复杂的条件判断
  4. 考虑状态对象的创建和管理策略
  5. 为复杂状态机提供配置和持久化支持

实现建议:

  1. 简单状态机可使用枚举实现
  2. 复杂状态机考虑表驱动或DSL配置
  3. 多线程环境需确保线程安全
  4. 性能敏感场景可优化状态查找
  5. 生产环境应添加状态监控和日志

状态模式与策略模式结构相似但意图不同:策略模式关注算法的可互换性,而状态模式关注行为随状态的变化。在复杂系统中,状态模式常与其他模式(如观察者、访问者、享元模式)结合使用,以构建更灵活的状态管理系统。