状态机的技术选型,yyds!

前言今天跟大家分享一个关于“状态机”的话题 。状态属性在我们的现实生活中无处不在 。比如电商场景会有一系列的订单状态(待支付、待发货、已发货、超时、关闭);员工提交请假申请会有申请状态(已申请、审核中、审核成功、审核拒绝、结束);差旅报销单会有单据审核状态(已提交、审核中、审核成功、退回、打款中、打款成功、打款失败、结束)等等 。上述场景有一个共同问题:根据不同触发条件执行不同处理动作最后落地不同的状态 。示例代码如下:
Integer status=0;    if(condition1){        status=1;    }else if(condition2){        status=2;    }else if(condition3){        status=3;    }else if(condition4){        status=4;    }复制代码那我们最容易能想到的自然是if-else方案 。那if-else方案会有什么问题呢?
主要有以下几点:

  • 复杂的业务流程 , if.else代码几乎无法维护
  • 随着业务的发展,业务过程也需要变更及扩展,但if.else代码段已经无法支持
  • 没有可读性,变更风险特别大,可能会牵一发而动全身,线上事故层出不穷
  • 其他业务逻辑可能也会跟if-else代码块耦合在一起,带来更多的问题

状态机的技术选型,yyds!

文章插图
状态机的出现就是用来解决上述问题的 。在复杂多状态流转情况下,通过状态机的引入,我们希望相关代码可读性、扩展性能比if-else方案更好!
关于状态机▲什么是状态机
状态机是有限状态自动机的简称 。有限状态机(英语:finite-state machine,缩写:FSM)又称有限状态自动机(英语:finite-state automaton,缩写:FSA),简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学计算模型 。
关于有限的解释:也就是被描述的事物的状态的数量是有限的 , 例如开关的状态只有“开”和“关”两个;灯的状态只有“亮”和“灭”等等 。
▲特点
一个状态机可以具有有限个特定的状态,它通常根据输入,从一个状态转移到另一个状态,不过也可能存在瞬时状态,而一旦任务完成,状态机就会立刻离开瞬时状态 。每个状态根据不同的前置条件,会从当前状态流转至下一个状态 。
▲作用
使用状态机来表达状态的流转 , 会使语义会更加清晰,会增强代码的可读性和可维护性 。
▲适用场景
面对复杂的状态流转(一般是超过三个及以上的状态流转),那么还是比较建议用状态机来实现的 。
状态机的技术选型,yyds!

文章插图
各个状态机方案▲枚举状态机
Java中的枚举是一个定义了一系列常量的特殊类(隐式继承自class java.lang.Enum) 。枚举类型因为自身的线程安全性保障和高可读性特性,是简单状态机的首选 。
关于线程安全说明我们随便自定义一个枚举:
public enum OpinionsEnum {    PASS,NOT_PASS}复制代码试着反编译上述代码:
public final class OpinionsEnum extends java.lang.Enum<OpinionsEnum> {  public static final OpinionsEnum PASS;  public static final OpinionsEnum NOT_PASS;  public static OpinionsEnum[] values();  public static OpinionsEnum valueOf(java.lang.String);  static {};}复制代码通过反编译后的代码我们看到:OpinionsEnum它继承了java.lang.Enum类;class前的final标识告诉我们此枚举类不能被继承 。
我们接着看它的两个属性:PASS、NOT_PASS 。它们无一例外都经过了staic 的修饰,而我们知道staic修饰的属性会在类被加载之后就完成初始化,而这个过程是线程安全的 。
示例代码:
public enum State {    SUBMIT_APPLY {        @Override        State transition(String checkcondition) {            System.out.println("员工提交请假申请单,同步流转到部门经理审批 参数 = " + checkcondition);            return Department_MANAGER_AUDIT;        }    },    Department_MANAGER_AUDIT {        @Override        State transition(String checkcondition) {            System.out.println("部门经理审批完成,同步跳转到HR进行审批 参数 = " + checkcondition);            return HR;        }    },    HR {        @Override        State transition(String checkcondition) {            System.out.println("HR完成审批,流转到结束组件, 参数 = " + checkcondition);            return FINAL;        }    },    FINAL {        @Override        State transition(String checkcondition) {            System.out.println("流程结束, 参数 = " + checkcondition);            return this;        }    };    abstract State transition(String checkcondition);}复制代码

推荐阅读