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

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 {

(编辑:莱芜站长网)

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

推荐文章
    热点阅读