EventBus 实现java状态机实例
发布时间:2023-02-20 11:04:21 所属栏目:Java 来源:互联网
导读:首先,了解状态机是什么,我们为什么需要状态机! 举个最简单例子,请假,作为一个最底层程序员,每次请假都要领导层层审批,而假有分为很多种,事假,病假,婚假,年休假等等,当然选择请的假不同,审批标准也不同,不同的假单需要走的审批链也不一样,比如
private static EventBus eventBus; static{ eventBus = new EventBus(); } /** * 发布一条假单 * @param leavePermit */ public static void post(LeavePermit leavePermit) { eventBus.post(leavePermit); } /** * 假单处理类 * @param statusLeavePermitHandler */ public static void addListener(LeavePermitHandler statusLeavePermitHandler) { eventBus.register(statusLeavePermitHandler); } } 所有假单的处理都会交给LeavePermitHandler去处理,这个对象里按照请假类型和请假状态做路由,选择不同的statusHandler处理业务逻辑。 public class LeavePermitHandler { //处理假单 注解代表可以接受到StatusMachineEngine发布的假单 @Subscribe @AllowConcurrentEvents public void handle(LeavePermit leavePermit){ //获取到状态处理类,然后去处理 handler为StatusHandler的入口 getStatusHandler(leavePermit).handle(leavePermit); } /** * 根据假单获取StatusHandler 状态处理对象 * @param leavePermit * @return */ public static StatusHandler getStatusHandler(LeavePermit leavePermit){ return StatusHandlerRegistry.acquireStatusHandler(leavePermit.getLeavePermitType(),leavePermit.getStatus()); } } 所有的状态处理类都会保存在StatusHandlerRegistry对象中,该对象负责注册所有有关请假类型,状态和状态处理类的关系,每次都根据请假类型和状态去获取StatusHandler。 public class StatusHandlerRegistry { private static Map<String,StatusHandler> statusHandlerMap; static { statusHandlerMap=new ConcurrentHashMap<String,StatusHandler>(); } private StatusHandlerRegistry(){ } private static String getKey(LeavePermitType leavePermitType,Status status){ return String.format("%s@-@%s",leavePermitType.getType(),status.name()); } /** * 注册状态处理类 * @param leavePermitType 请假类型 * @param status 请假状态 * @param statusHandler 状态处理对象 */ public static void registryStatusHandler(LeavePermitType leavePermitType,Status status,StatusHandler statusHandler){ statusHandlerMap.put(getKey(leavePermitType,status),statusHandler); } /** * 获取状态处理类 * @param leavePermitType 请假类型 * @param status 请假状态 * @return StatusHandler */ public static StatusHandler acquireStatusHandler(LeavePermitType leavePermitType,Status status){ return statusHandlerMap.get(getKey(leavePermitType,status)); } } 所以,在我们项目启动中,将请假类型,请假状态和状态处理对象StatusHandler注册到StatusHandlerRegistry中,当LeavePermitHandler 处理类接收到StatusHandlerEngine.post()的假单的时候,可以根据请假类型和状态获取相应的处理类StatusHandler,做相应状态逻辑的处理,逻辑处理结束,是否继续状态机取决于statusHandler的after方法是否调用goNextStatusHandler(leavePermit);在调用goNextStatusHandler(leavePermit)的时候,会去状态机获取下一个状态,StatusHandlerEngine.post(leavePermit)将继续去获取处理类statusHandler,这个时候,应为leavePermit的状态已经发生变化,所以获取到的statusHandler已经发生变化。 看一下运行结果: public static void main(String[] args) { //注册年休假的状态和对应状态的处理类StatusHandler。 registryAnnualPermitStatusHandler(); //注册病假的状态和对应状态的处理类StatusHandler。 registryMedicalPermitStatusHandler(); LeavePermitHandler leavePermitHandler=new LeavePermitHandler(); //状态机引擎接受事件处理类 StatusMachineEngine.addListener(leavePermitHandler); //生成假单 LeavePermit leavePermit=new LeavePermit(); leavePermit.setLeavePermitType(LeavePermitType.ANNUAL_LEAVE); leavePermit.setStatus(Status.PERMIT_SUBMIT); leavePermit.setUser("jettyrun"); //假单交给引擎去执行 StatusMachineEngine.post(leavePermit); System.out.println("----- 分割线 代表假条需要领导审批了,领导给个通过意见,然后状态机接着走-------"); leavePermit.setEvent(Event.AGREE); StatusMachineEngine.post(leavePermit); System.out.println("----- 分割线 代表假条需要ceo审批了,ceo给个通过意见,然后状态机接着走-------"); leavePermit.setEvent(Event.AGREE); StatusMachineEngine.post(leavePermit); System.out.println("--->>>>>>>>>end<<<<<<<<-------"); } public static void registryAnnualPermitStatusHandler() { StatusHandlerRegistry.registryStatusHandler(LeavePermitType.ANNUAL_LEAVE,Status.PERMIT_SUBMIT,new AnnualPermitSubmitStatusHandler()); (编辑:莱芜站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |