在Java中用規則引擎模式替代ifelse - Vitali
規則引擎模式:這種模式的本質是if - else ,拆分if - else每個分支到規則類中,然後,主規則引擎類將儲存所有規則並找到與客戶端請求匹配的規則。
定義規則類
為了確保所有規則類都實現相同的方法,讓我們定義一個每個類都將實現的介面:
public interface AncestorRule { Optional<AncestorResult> evaluate(String selector); } |
接下來,讓我們定義第一個規則類。該類將儲存if - else分支中定義的邏輯:
public class AncestorWithClassRule implements AncestorRule { @Override public Optional<AncestorResult> evaluate(String selector) { if (isCssClass(selector)) { String xpath = format( "ancestor::*[contains(concat(' ', normalize-space(@class), ' '), ' %s ')][%s]", selector.substring(1) ); return Optional.of(new AncestorResult(xpath)); } return Optional.empty(); } } |
isCssClass()判斷如果它是一個 CSS 類,則會構建一個 XPath 表示式並將其作為一i個Optional 返回。
這個規則類乾淨、簡短、易於理解。一次編寫,不需要經常修改,除非規則的業務邏輯有更新。
我們以同樣的方式定義其他規則。驗證輸入是否與給定條件匹配,構建並返回相應的 XPath 表示式。否則,結果為空。
規則結果
上面的程式碼使用了AncestorResult. 這個類的目的是包裝成功評估的結果。這個類如下所示:
public class AncestorResult { private final String value; public AncestorResult(String value) { this.value = value; } public String getValue() { return value; } } |
只是我們透過建構函式設定的一個類欄位並使用 getter 訪問它。
規則引擎類
現在,讓我們最終進入包含規則引擎邏輯的類。
public class AncestorRuleEngine { private static final List<AncestorRule> rules = Arrays.asList( new AncestorWithTagRule(), new AncestorWithClassRule(), new AncestorWithAttributeRule(), new AncestorWithAttributeAndValueRule() ); public AncestorResult process(String selector) { return rules .stream() .map(rule -> rule.evaluate(selector)) .flatMap(optional -> optional.map(Stream::of).orElseGet(Stream::empty)) .findFirst() .orElseThrow(() -> new IllegalArgumentException("Selector does not match any rule")); } } |
在這個類中做的第一件事是一個適用於這個域的所有規則的靜態列表。如果我們有一個新規則——我們實現一個新類並將它新增到這個規則列表中。
第二件事是跨所有規則處理客戶端的輸入。它流式傳輸規則列表,評估每個規則。規則的第一個非空結果被返回給客戶端。否則,規則引擎將丟擲異常。
前一個map()函式返回一個可選的流。然後, flatMap()將空 Optionals 流轉換為空流。否則,將一個非空的 AncestorResults 流封裝到 Optional 中。該構造與 Java 8 相容並且看起來很冗長。幸運的是,從 Java 9 開始,這可以簡化。
規則引擎的使用
現在,當我們實現了所有或規則時,規則引擎就定義好了,讓我們看看如何呼叫和使用這個引擎。
public class ClientSideThatCallsTheRuleEngine { public void executeClientCode() { // some executions AncestorRuleEngine ruleEngine = new AncestorRuleEngine(); String xpath = ruleEngine.process(selector).getValue(); // other executions } |
它是如此簡單。例項化規則引擎。傳入客戶端的輸入,得到結果。它乾淨、簡短且精確。我們隱藏了驗證輸入、構建相應結果、處理它的所有低階邏輯。將其與具有多個if - else分支的直接方法進行比較。我們新增的邏輯越多,這個if - else怪物就會成長得越多。
相關文章
- 規則引擎模式 - upperdine模式
- 如何學習Java的規則引擎模式? - plagovJava模式Go
- Java各種規則引擎Java
- Java規則引擎 Easy RulesJava
- Rust中用元組模式匹配替代if-elseRust模式
- 規則引擎在IoT的重要性?
- uwegeercken/jare:Java業務規則引擎(Jare)JARJava
- URule規則引擎
- 開放封閉原則與規則引擎設計模式 - devgenius設計模式dev
- 規則引擎模式的.NET開源專案案例模式
- 用 Java 構建簡單的規則引擎Java
- .NET RulesEngine(規則引擎)
- 風控規則引擎(一):Java 動態指令碼Java指令碼
- 使用DDD規格Specification模式構建資料驅動規則引擎 - jonblankenship模式
- 架構 規則引擎 quartz架構quartz
- Drools 規則引擎應用
- Drools規則引擎簡介
- 決策表模式: 一種業務規則引擎實現方式模式
- j-easy/easy-rules: Java簡單的規則引擎Java
- Java中最流行的幾種業務規則引擎簡介Java
- 什麼是規則引擎? - martinfowler
- Evrete 規則引擎簡介 | baeldungVR
- 規則引擎Golang指南 – Mohit KhareGolang
- 快速整合和使用 drools 規則引擎
- 什麼是業務規則引擎?
- 全渠道營銷規則引擎案例
- Spring Boot + liteflow 規則引擎,太香了!Spring Boot
- 規則引擎開發經驗分享 - reddit
- Devs--開源規則引擎介紹dev
- Drools 業務規則引擎的完整教程
- 如何用Go快速實現規則引擎Go
- Drools規則引擎實踐直白總結
- 規則引擎與ML模型的比較 - xLaszlo模型
- 數字化轉型中的規則引擎
- 一個規則引擎的視覺化方案視覺化
- 第2-4-4章 規則引擎Drools規則屬性-業務規則管理系統-元件化-中臺元件化
- 通過規則引擎跟蹤Java執行狀態的檢測工具:BytemanJava
- Java中用正則從HTML標籤中提取文字2種方法JavaHTML