分类: 高性能计算
2023-01-28 11:51:50
Squirrel 状态机是一种用来进行对象行为建模的工具,主要描述对象在它的生命周期内所经历的状态,以及如何响应来自外界的各种事件。比如订单的创建、已支付、发货、收获、取消等等状态、状态之间的控制、触发事件的监听,可以用该框架进行清晰的管理实现。使用状态机来管理对象生命流的好处更多体现在代码的可维护性、可测试性上,明确的状态条件、原子的响应动作、事件驱动迁移目标状态,对于流程复杂易变的业务场景能大大减轻维护和测试的难度。
Squirrel 状态机是一种有限状态机,有限状态机是指对象有一个明确并且复杂的生命流(一般而言三个以上状态),并且在状态变迁存在不同的触发条件以及处理行为。
Squirrel 状态机可归纳为 4 个要素,即现态、条件、动作、次态。“现态” 和 “条件” 是因,“动作” 和 “次态” 是果。
举例,京东线上开店需要经过审核才能正式上线,店铺状态有待审核、已驳回、已审核,对应操作有提交审核,审核通过,审核驳回动作。现在需要实现一个店铺审核流程的需求。
图 1.if-else/switch-case 模式实现流程图
图 2. 状态机模式实现流程图
通过引入状态机,可以去除大量 if-else if-else 或者 switch-case 分支结构,直接通过当前状态和状态驱动表查询行为驱动表,找到具体行为执行操作,有利于代码的维护和扩展。
图 3. 状态机创建流程图
<dependency> <groupId>org.squirrelframeworkgroupId> <artifactId>squirrel-foundationartifactId> <version>0.3.9version> dependency>
// 店铺审核状态 public Enum ShopInfoAuditStatusEnum{ audit(0,"待审核"), agree(1,"审核通过"), reject(2,"审核驳回");
} // 店铺审核事件 public Enum ShopInfoAuditEvent{ SUBMIT, // 提交 AGREE, // 同意 REJECT; // 驳回 }
/**
* StateMachineBuilder实例
*/ public class StateMachineEngine <T extends UntypedStateMachine, S, E, C> implements ApplicationContextAware{ private ApplicationContext applicationContext; private static Map builderMap = new HashMap(); @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext;
} @Transactional public void fire(Class machine, S state, E event, C context) {
StateMachineBuilder stateMachineBuilder = this.getStateMachineBuilder(machine);
StateMachine stateMachine = stateMachineBuilder.newStateMachine(state,applicationContext);
stateMachine.fire(event, context);
} private StateMachineBuilder getStateMachineBuilder(Class stateMachine) {
UntypedStateMachineBuilder stateMachineBuilder = builderMap.get(stateMachine.getName()); if(stateMachineBuilder == null){
stateMachineBuilder = StateMachineBuilderFactory.create(stateMachine,ApplicationContext.class);
builderMap.put(stateMachine.getName(),stateMachineBuilder);
} return stateMachineBuilder;
/**
* 店铺审核状态机
*/ @States({ @State(name = "audit"), @State(name = "agree"), @State(name = "reject")
}) @Transitions({ @Transit(from = "audit", to = "agree", on = "AGREE", callMethod = "agree"), @Transit(from = "audit", to = "reject", on = "REJECT", callMethod = "reject"), @Transit(from = "reject", to = "audit", on = "SUBMIT", callMethod = "submit"), @Transit(from = "agree", to = "audit", on = "SUBMIT", callMethod = "submit"), @Transit(from = "audit", to = "audit", on = "SUBMIT", callMethod = "submit"),
}) @StateMachineParameters(stateType=ShopInfoAuditStatusEnum.class, eventType=ShopInfoAuditEvent.class, contextType=ShopInfoAuditStatusUpdateParam.class) public class ShopInfoAuditStateMachine extends AbstractUntypedStateMachine { private ApplicationContext applicationContext; public ShopInfoAuditStateMachine(){} public ShopInfoAuditStateMachine(ApplicationContext applicationContext) { this.applicationContext = applicationContext;
} // 审核通过业务逻辑 public void agree(ShopInfoAuditStatusEnum fromState, ShopInfoAuditStatusEnum toState, ShopInfoAuditEvent event, ShopInfoAuditStatusUpdateParam param) { this.agree(fromState,toState,event,param);
} // 审核驳回业务逻辑 public void reject(ShopInfoAuditStatusEnum fromState, ShopInfoAuditStatusEnum toState, ShopInfoAuditEvent event, ShopInfoAuditStatusUpdateParam param) { this.reject(fromState,toState,event,param);
} // 提交业务逻辑 public void submit(ShopInfoAuditStatusEnum fromState, ShopInfoAuditStatusEnum toState, ShopInfoAuditEvent event, ShopInfoAuditStatusUpdateParam param) { this.submit(fromState,toState,event,param);
}
// 调用端 main{
StateMachineEngine stateMachineEngine = applicationContext.getBean(StateMachineEngine.class); // 审核通过调case stateMachineEngine.fire(ShopInfoAuditStateMachine.class,ShopInfoAuditStatusEnum.audit,ShopInfoAuditEvent.AGREE,param); // 审核驳回case stateMachineEngine.fire(ShopInfoAuditStateMachine.class,ShopInfoAuditStatusEnum.audit,ShopInfoAuditEvent.REJECT,param); }
状态机很好的帮我们处理了对象状态的流转、事件的监听以及外界的各种事件的响应。从代码设计角度减少了大量 if-else/switch-case 逻辑判断,提高了代码的可维护性、扩展性,方便管理和测试。