← 返回首页
🧩

状态模式:有限状态机与工作流引擎

📂 architecture ⏱ 3 min 507 words

状态模式:有限状态机与工作流引擎

状态模式核心思想

状态模式允许对象在内部状态改变时改变其行为,对象看起来好像修改了其类。状态模式将状态相关的行为封装到独立的状态类中,消除了大量的条件分支语句。在架构中,状态模式是工作流引擎和有限状态机(FSM)的基础。

// 状态接口
public interface OrderState {
    void next(OrderContext context);
    void prev(OrderContext context);
    void cancel(OrderContext context);
    String getStateName();
}

// 具体状态
public class CreatedState implements OrderState {
    @Override
    public void next(OrderContext context) {
        // 创建 -> 已支付
        context.setState(new PaidState());
    }
    
    @Override
    public void prev(OrderContext context) {
        throw new IllegalStateException("Created state has no previous state");
    }
    
    @Override
    public void cancel(OrderContext context) {
        // 创建 -> 已取消
        context.setState(new CancelledState());
    }
    
    @Override
    public String getStateName() { return "CREATED"; }
}

public class PaidState implements OrderState {
    @Override
    public void next(OrderContext context) {
        context.setState(new ShippedState());
    }
    
    @Override
    public void prev(OrderContext context) {
        context.setState(new CreatedState());
    }
    
    @Override
    public void cancel(OrderContext context) {
        context.setState(new CancelledState());
    }
    
    @Override
    public String getStateName() { return "PAID"; }
}

// 状态上下文
public class OrderContext {
    private OrderState currentState;
    
    public OrderContext() {
        this.currentState = new CreatedState();
    }
    
    public void setState(OrderState state) {
        log.info("State transition: {} -> {}", currentState.getStateName(), state.getStateName());
        this.currentState = state;
    }
    
    public void next() { currentState.next(this); }
    public void prev() { currentState.prev(this); }
    public void cancel() { currentState.cancel(this); }
}

审批流程状态机

审批流程是状态模式的典型应用,每个审批节点封装独立的行为逻辑。

from abc import ABC, abstractmethod
from typing import Optional

class ApprovalState(ABC):
    @abstractmethod
    def approve(self, context: 'ApprovalContext') -> None: ...
    
    @abstractmethod
    def reject(self, context: 'ApprovalContext', reason: str) -> None: ...
    
    @abstractmethod
    def get_status(self) -> str: ...

class PendingApproval(ApprovalState):
    def approve(self, context: 'ApprovalContext') -> None:
        context.set_state(ManagerApproval())
    
    def reject(self, context: 'ApprovalContext', reason: str) -> None:
        context.set_state(Rejected(reason))
    
    def get_status(self) -> str:
        return "PENDING"

class ManagerApproval(ApprovalState):
    def approve(self, context: 'ApprovalContext') -> None:
        context.set_state(DirectorApproval())
    
    def reject(self, context: 'ApprovalContext', reason: str) -> None:
        context.set_state(Rejected(reason))
    
    def get_status(self) -> str:
        return "MANAGER_APPROVAL"

class DirectorApproval(ApprovalState):
    def approve(self, context: 'ApprovalContext') -> None:
        context.set_state(Approved())
    
    def reject(self, context: 'ApprovalContext', reason: str) -> None:
        context.set_state(Rejected(reason))
    
    def get_status(self) -> str:
        return "DIRECTOR_APPROVAL"

class Approved(ApprovalState):
    def approve(self, context: 'ApprovalContext') -> None:
        raise IllegalStateException("Already approved")
    
    def reject(self, context: 'ApprovalContext', reason: str) -> None:
        raise IllegalStateException("Cannot reject approved request")
    
    def get_status(self) -> str:
        return "APPROVED"

class Rejected(ApprovalState):
    def __init__(self, reason: str):
        self.reason = reason
    
    def approve(self, context: 'ApprovalContext') -> None:
        context.set_state(PendingApproval())
    
    def reject(self, context: 'ApprovalContext', reason: str) -> None:
        raise IllegalStateException("Already rejected")
    
    def get_status(self) -> str:
        return "REJECTED"

class ApprovalContext:
    def __init__(self):
        self._state = PendingApproval()
        self._history = []
    
    def set_state(self, state: ApprovalState):
        self._history.append(self._state.get_status())
        self._state = state
    
    def approve(self):
        self._state.approve(self)
    
    def reject(self, reason: str):
        self._state.reject(self, reason)
    
    def get_status(self) -> str:
        return self._state.get_status()

工作流引擎中的状态管理

工作流引擎使用状态模式管理流程实例的生命周期,支持并行状态、超时处理和条件分支。

// 工作流状态机
type WorkflowState = 
  | { type: 'INITIAL' }
  | { type: 'RUNNING'; currentNode: string }
  | { type: 'PAUSED'; currentNode: string; pausedAt: Date }
  | { type: 'COMPLETED'; result: any }
  | { type: 'FAILED'; error: string };

class WorkflowStateMachine {
  private state: WorkflowState = { type: 'INITIAL' };
  private transitions = new Map<string, (state: WorkflowState) => WorkflowState>();
  
  constructor() {
    this.transitions.set('START', (s) => {
      if (s.type !== 'INITIAL') throw new Error('Cannot start from non-initial state');
      return { type: 'RUNNING', currentNode: 'start' };
    });
    
    this.transitions.set('COMPLETE_NODE', (s) => {
      if (s.type !== 'RUNNING') throw new Error('Workflow not running');
      return { type: 'RUNNING', currentNode: 'next_node' };
    });
    
    this.transitions.set('PAUSE', (s) => {
      if (s.type !== 'RUNNING') throw new Error('Cannot pause non-running workflow');
      return { type: 'PAUSED', currentNode: s.currentNode, pausedAt: new Date() };
    });
  }
  
  transition(event: string): void {
    const handler = this.transitions.get(event);
    if (!handler) throw new Error(`Unknown transition: ${event}`);
    this.state = handler(this.state);
  }
}