加入收藏 | 设为首页 | 会员中心 | 我要投稿 莱芜站长网 (https://www.0634zz.com/)- 云连接、建站、智能边缘云、设备管理、大数据!
当前位置: 首页 > 编程开发 > Java > 正文

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());

(编辑:莱芜站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读