状态模式:有限状态机与工作流引擎
状态模式:有限状态机与工作流引擎
状态模式核心思想
状态模式允许对象在内部状态改变时改变其行为,对象看起来好像修改了其类。状态模式将状态相关的行为封装到独立的状态类中,消除了大量的条件分支语句。在架构中,状态模式是工作流引擎和有限状态机(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);
}
}