1. 订单状态机基础实现
任务目标
实现一个订单状态机,覆盖订单从创建到完成的完整生命周期。状态包括:CREATED(已创建)、PAID(已支付)、SHIPPED(已发货)、COMPLETED(已完成)。支持通过事件触发合法状态转换,并拒绝非法转换。
状态转换规则
| 当前状态 | 触发事件 | 目标状态 |
|---|---|---|
| CREATED | PAY | PAID |
| PAID | SHIP | SHIPPED |
| SHIPPED | COMPLETE | COMPLETED |
任何其他状态-事件组合均为非法转换,应抛出异常或返回错误。
完整实现代码
// order_state_machine.js
// 运行环境:Node.js 12+,无需第三方依赖
class OrderStateMachine {
// 状态定义
static STATES = {
CREATED: 'CREATED',
PAID: 'PAID',
SHIPPED: 'SHIPPED',
COMPLETED: 'COMPLETED'
};
// 合法转换表:{ 当前状态: { 事件: 目标状态 } }
static TRANSITIONS = {
[OrderStateMachine.STATES.CREATED]: {
PAY: OrderStateMachine.STATES.PAID
},
[OrderStateMachine.STATES.PAID]: {
SHIP: OrderStateMachine.STATES.SHIPPED
},
[OrderStateMachine.STATES.SHIPPED]: {
COMPLETE: OrderStateMachine.STATES.COMPLETED
}
};
constructor(orderId) {
this.orderId = orderId;
this.state = OrderStateMachine.STATES.CREATED; // 初始状态
this.history = []; // 状态变更历史
}
// 触发事件,返回是否转换成功
trigger(event) {
const currentTransitions = OrderStateMachine.TRANSITIONS[this.state];
const nextState = currentTransitions ? currentTransitions[event] : undefined;
if (!nextState) {
throw new Error(
`非法转换: 订单 ${this.orderId} 当前状态 ${this.state} 不能响应事件 ${event}`
);
}
this.history.push({
from: this.state,
to: nextState,
event: event,
timestamp: new Date().toISOString()
});
this.state = nextState;
return true;
}
// 获取当前状态
getState() {
return this.state;
}
// 获取完整历史记录
getHistory() {
return this.history;
}
}
// ========== 最小调用入口与验证 ==========
function runDemo() {
const order = new OrderStateMachine('ORD-2024-001');
const results = [];
// 1. 正常流程:创建 → 支付 → 发货 → 完成
results.push(`初始状态: ${order.getState()}`);
order.trigger('PAY');
results.push(`支付后: ${order.getState()}`);
order.trigger('SHIP');
results.push(`发货后: ${order.getState()}`);
order.trigger('COMPLETE');
results.push(`完成后: ${order.getState()}`);
// 2. 非法转换验证:已完成订单再次支付应报错
try {
order.trigger('PAY');
results.push('非法转换未被拦截(错误)');
} catch (e) {
results.push(`非法转换被正确拦截: ${e.message}`);
}
// 3. 输出历史记录
results.push('历史记录:');
order.getHistory().forEach(h => {
results.push(` ${h.from} --${h.event}--> ${h.to} @ ${h.timestamp}`);
});
return results.join('\n');
}
// 执行演示
console.log(runDemo());
运行方式
node order_state_machine.js
验证方法与通过标准
运行上述命令后,观察控制台输出,满足以下条件即判定实现正确:
- 输出依次包含
初始状态: CREATED、支付后: PAID、发货后: SHIPPED、完成后: COMPLETED,证明正常状态链路完整走通。 - 输出包含
非法转换被正确拦截: 非法转换: 订单 ORD-2024-001 当前状态 COMPLETED 不能响应事件 PAY,证明非法事件被拒绝。 - 历史记录中列出3条转换记录,每条包含
from --event--> to格式及时间戳。
预期输出(与代码逻辑严格一致)
初始状态: CREATED
支付后: PAID
发货后: SHIPPED
完成后: COMPLETED
非法转换被正确拦截: 非法转换: 订单 ORD-2024-001 当前状态 COMPLETED 不能响应事件 PAY
历史记录:
CREATED --PAY--> PAID @ 2024-01-01T00:00:00.000Z
PAID --SHIP--> SHIPPED @ 2024-01-01T00:00:00.000Z
SHIPPED --COMPLETE--> COMPLETED @ 2024-01-01T00:00:00.000Z
(时间戳为运行时动态生成,格式如上所示,具体值以实际执行为准。)
核心设计说明
状态机采用查表法实现:TRANSITIONS 静态对象定义了所有合法转换路径,trigger() 方法先查表判断目标状态是否存在,不存在则抛出异常。这种实现方式将状态转换规则集中管理,新增状态或事件时只需修改转换表,无需改动业务逻辑代码。历史记录数组完整追踪每次状态变更,便于审计与调试。