當前位置: 妍妍網 > 碼農

我用這個技術,幹掉幾千行 if else!

2024-03-16碼農

大家好我是魚皮,今天我將用一個有趣的小例子來帶大家入門企業開發中非常實用的技術—— 工作流,用好這個技術,可以幫你消除計畫中大量的 if else 程式碼,讓你的計畫更好維護和擴充套件。

本文視訊演示:https://www.bilibili.com/video/BV13d4y1o7iB/

什麽是工作流?

工作流顧名思義,就是一系列工作所組成的流程。

就像工廠加工產品一樣,確認好生產步驟後,所有工人只需做好自己的事情即可。

比如我現在要做一個養雞系統, 每一只雞都需要依次透過唱、跳、RAP、籃球的考核,並且還要練習時長兩年半,才能出售,否則就算是 「蔡雞」,要打回去重新練習。

對應的流程圖如下:

那如果讓你來寫程式碼實作這個邏輯,你會怎麽寫呢?

想必會是一大段的 if ... else ... 吧,像下面這樣:

對於簡單的程式來說,這樣寫沒有問題。但在企業開發中,我們的業務流程往往是非常復雜的,比如下面這個系統:

再加上多人協作開發,大家都在一個檔裏寫 if else 也不現實。

所以為了更好地開發和維護工作流,我們一般會使用 工作流引擎 技術。可以透過視覺化拖拽的方式來繪制流程圖、並自動生成業務流程程式碼,而不用自己寫 if else,大幅降低開發成本、非程式設計師也能用。

視覺化繪制工作流

比較成熟的工作流引擎有 Activiti、flowable-engine 等等,但它們都需要一些學習成本,對於第一次接觸工作流的同學來說,可能會有點復雜。

所以我選了一個相對輕量純凈的工作流引擎 CompileFlow 來演示,便於大家理解。

下面我們用它來實作剛剛提到的養雞系統。

工作流實作養雞系統

1、準備操作

使用 Compile Flow 非常簡單,直接進入程式碼倉庫主頁,引入程式碼包即可:

這裏我建議大家首次使用時下載官方提供的範例程式碼:https://github.com/compileflow/compileflow-demo

這是一個 Maven + Spring Boot 的計畫,我們用 IDEA 開發工具開啟它,可以看到目錄中有很多 bpm 業務流程管理檔,用來定義我們的工作流。

但是 bpm 檔是用 XML 編寫的,看著就很復雜,真要自己寫這個玩意還不如寫 if else 呢!

bpm 檔

所以我們要先下載一個 Compileflow Designer 外掛程式,這樣就能視覺化地編輯工作流了:

2、新建計畫

讓我們在資源目錄下新建一個 bpm 檔,就叫 ji.bpm ,然後點編輯器底部切換到視覺化編輯檢視。

在這裏,我們就能像畫流程圖一樣設計我們的程式流程了,讓我們試著復現一下之前畫的流程圖。

視覺化編輯流程

左邊的內容稱為 節點 ,每個流程圖必須包含一個開始和一個結束節點,不同的節點有不同的流程控制規則。

節點又可以指向其他節點,表示工作的執行順序,雙擊節點可以編輯節點名稱:

編輯節點

一番操作後,我們的流程圖就變成了下面這個樣子:

但目前這個流程圖是靜態的,我們需要給它繫結數據和程式程式碼,來讓整個流程動起來。

3、繫結數據

我們要先確定整個流程的輸入和輸出,此處我們的輸入就是一只雞(Ji 物件)、輸出是考核結果(boolean 型別),我們把這些資訊叫做工作流的 上下文 。可以理解為全域變量,工作流的每個節點都可以讀取這些數據。

確定上下文

雙擊編輯器空白處,就可以配置上下文。這裏要註意選擇 inOutType 的值,全域入參為 param、全域返回值為 result,如果你需要在部份節點中傳遞變量,可以用 inner 型別。

全域上下文配置

4、繫結方法

配置好上下文後,我們要給每個節點繫結一個方法,也就是這個節點要做什麽事。

這裏我們從之前的 if else 程式中提取出需要的方法,每個分支都是一個獨立的方法,比如 checkChang、考核成功、考核失敗等:

每個節點一個方法

然後雙擊流程圖中的節點,點選行為配置,選擇我們的方法,配置輸入參數和返回值。這裏我們的輸入參數從上下文中獲取,返回值同步給上下文,配置如圖:

繫結方法

5、繫結條件

最後我們還要再給判斷節點繫結條件,區分 yes 或 no。

單擊箭頭,然後輸入運算式,如果運算式成立,那麽會往下執行,還可以配置優先級來選擇判斷順序(類似程式碼中 if else 的順序):

繫結條件

6、執行流程

至此,我們的流程圖就編輯完了,然後我們就可以在程式碼中執行流程。

比如我這裏新建一個 main 方法,new 一只雞,作為輸入參數放到流程上下文中,然後呼叫流程引擎的 start 方法,就能得到結果了。

範例程式碼如下:

publicstaticvoidmain(String[] args){
// 輸入一只雞
Ji ji = new Ji();
ji.setName("cai");
ji.setCanChang(true);
ji.setCanTiao(true);
ji.setCanRap(true);
ji.setCanLanQiu(true);
ji.setPracticeYear(2.5D);
// 找到 bpm 檔的位置
String code = "bpm.ji";
// 設定上下文(輸入參數)
Map<String, Object> context = new HashMap<>();
context.put("ji", ji);
try {
// 執行流程
ProcessEngine processEngine = ProcessEngineFactory.getProcessEngine();
Map<String, Object> result = processEngine.start(code, context);
// 獲取結果
System.out.println(result.get("result"));
catch (Exception e) {
e.printStackTrace();
}
}

執行一下試試看:

大功告成,以上就是工作流引擎的用法了。

不過由於這個例子比較簡單,可能無法突出工作流引擎的優勢,這也說明了一點:任何技術都要結合實際場景來選擇是否運用。

一般工作流引擎在 ERP 系統、OA 系統中用的比較多,那大家感興趣的話也可以試著完成 demo 計畫中更復雜的例子 orderFulfillmentFlow.bpm ,感受工作流引擎開發的高效。

更復雜的例子

原理

Compile Flow 工作流引擎的原理其實也很 「簡單」,就是將使用者編輯好的 XML 檢視檔編譯為 Java 程式碼。我們點開編譯後的 Java 程式碼就可以看到全域變量、流程等等:

雖然說還是用到了 if else,但是開發者不需要關心這些 if else 了,定義好流程、寫好每個節點要做的工作即可。


最後補充一句,Compile Flow 其實好久沒更新了,文件寫的也過於精簡。我只是為了便於大家理解,給大家演示使用。如果你想系統地學習或在企業開發中使用工作流,還是更推薦 Activiti 等成熟的,國產好用的工作流引擎也很多。

以上就是本期分享,學會的朋友們點個贊吧,之後大家如果忘了工作流,就想想唱跳 RAP 籃球。

歡迎學編程的朋友們加入我的 (點選了解詳情),一起學習進步~

往期推薦