狀態機的技術選型,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);}復制代碼

推薦閱讀