EventBus 实现java状态机实例
发布时间:2023-02-20 11:04:21 所属栏目:Java 来源:互联网
导读:首先,了解状态机是什么,我们为什么需要状态机! 举个最简单例子,请假,作为一个最底层程序员,每次请假都要领导层层审批,而假有分为很多种,事假,病假,婚假,年休假等等,当然选择请的假不同,审批标准也不同,不同的假单需要走的审批链也不一样,比如
default: throw new RuntimeException("未知类型"); } } } 状态机设计好之后,每个状态都应该对应有该状态的处理类,且需要统一管理该状态和处理类的关系。 以年休假为例:提交假单->领导审批4个状态->ceo审批4个状态->请假完成/失败2个状态。 总计需要11个状态处理对象去处理该状态。 该状态处理类需要具备哪些能力: 处理该状态的业务 能够决定要不要扭转该状态机接着往下走(提交假单状态处理结束要能够自动运行到领导审批状态,领导审批状态不能接着扭转到下一个状态,需要等待领导的审批意见才可继续往下走) 不难设计,先抽象出一个StatusHandler接口或父类,每个状态的处理类去实现该接口或继承该父类,在statusHandler中,有三个方法,before,dohandler,after,after主要负责扭转状态机,获取下一个状态的处理类处理下一个状态的事件。如果状态到达某一个状态不需要往下继续执行,则重写after方法即可中断状态机,dohandler主要负责做业务处理。 public interface AbstractStatusHandler { public void handle(LeavePermit leavePermit); } public abstract class StatusHandler implements AbstractStatusHandler{ protected void before(LeavePermit leavePermit){ } public void handle(LeavePermit leavePermit){ before(leavePermit); doHandler(leavePermit); after(leavePermit); } protected abstract void doHandler(LeavePermit leavePermit); protected void after(LeavePermit leavePermit){ //去下一个状态的处理对象处理 goNextStatusHandler(leavePermit); } protected void goNextStatusHandler(LeavePermit leavePermit){ //获取下一个状态 leavePermit.setStatus(StatusMachineFactory.getStatusMachine(leavePermit.getLeavePermitType()).getNextStatus(leavePermit.getStatus(),leavePermit.getEvent())); //状态机引擎驱动假单处理 StatusMachineEngine.post(leavePermit); } 在看一下具体的状态处理类实现,11个状态对应11个处理类,这里列举出部分 public class AnnualPermitSubmitStatusHandler extends StatusHandler{ protected void doHandler(LeavePermit leavePermit){ System.out.println(String.format("user:%s--提交年休假假单--leavePermit status:%s",leavePermit.getUser(),leavePermit.getStatus().getStatus())); } } public class AnnualleaderPermitingStatusHandler extends StatusHandler{ protected void doHandler(LeavePermit leavePermit){ System.out.println(String.format("user:%s--领导审批年休假中--leavePermit status:%s",leavePermit.getStatus().getStatus())); } @Override protected void after(LeavePermit leavePermit){ if(leavePermit.getEvent()==null){ //还未审批,状态机结束,等待审批意见 System.out.println(String.format("user:%s--等待领导审批--leavePermit status:%s",leavePermit.getStatus().getStatus())); return; } super.goNextStatusHandler(leavePermit); } } public class AnnualleaderAgreeStatusHandler extends StatusHandler{ protected void doHandler(LeavePermit leavePermit){ System.out.println(String.format("user:%s--直线领导同意请年休假--leavePermit status:%s",leavePermit.getStatus().getStatus())); } } public class AnnualleaderAgreeStatusHandler extends StatusHandler{ protected void doHandler(LeavePermit leavePermit){ leavePermit.setEvent(null); System.out.println(String.format("user:%s--直线领导同意请年休假--leavePermit status:%s",leavePermit.getStatus().getStatus())); } } public class AnnualCEOPermitingStatusHandler extends StatusHandler{ protected void doHandler(LeavePermit leavePermit){ System.out.println(String.format("user:%s--ceo审批年休假中--leavePermit status:%s",leavePermit.getStatus().getStatus())); } protected void after(LeavePermit leavePermit){ if(leavePermit.getEvent()==null){ //还未审批,状态机结束,等待审批意见 System.out.println(String.format("user:%s--等待ceo审批--leavePermit status:%s",leavePermit.getStatus().getStatus())); return; } goNextStatusHandler(leavePermit); } } public class AnnualCEOAgreeStatusHandler extends StatusHandler{ protected void doHandler(LeavePermit leavePermit){ System.out.println(String.format("user:%s--ceo同意休年休假--leavePermit status:%s",leavePermit.getStatus().getStatus())); } } public class AnnualPermitSuccessstatusHandler extends StatusHandler{ @Override protected void doHandler(LeavePermit leavePermit){ System.out.println(String.format("user:%s--请年休假假成功--leavePermit status:%s",leavePermit.getStatus().getStatus(),leavePermit.getStatus().getMemo())); } @Override protected void after(LeavePermit leavePermit){ } } 关于假单的请求,都会由StatusMachineEngine.post(LeavePermit)去处理,这里是如何做到按照请假类型,和状态找到对应的statusHandler的? 这里是使用eventbus去实现(基于消息订阅发布模式实现) public class StatusMachineEngine { (编辑:莱芜站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |