在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怪物就會成長得越多。
相關文章
- 【java規則引擎】規則引擎RuleBase中利用觀察者模式Java模式
- 【java規則引擎】之規則引擎解釋Java
- 規則引擎模式 - upperdine模式
- 【java規則引擎】java規則引擎搭建開發環境Java開發環境
- 如何學習Java的規則引擎模式? - plagovJava模式Go
- Java規則引擎 Easy RulesJava
- Java各種規則引擎Java
- [Drools]JAVA規則引擎 -- DroolsJava
- uwegeercken/jare:Java業務規則引擎(Jare)JARJava
- java 規則引擎資料彙集Java
- Rust中用元組模式匹配替代if-elseRust模式
- 【java規則引擎】簡單規則的rete網路示意圖Java
- 【java規則引擎】一個基於drools規則引擎實現的數學計算例子Java
- 開放封閉原則與規則引擎設計模式 - devgenius設計模式dev
- 規則引擎模式的.NET開源專案案例模式
- 用 Java 構建簡單的規則引擎Java
- 【java規則引擎】之Drools之Rete演算法Java演算法
- 風控規則引擎(一):Java 動態指令碼Java指令碼
- 架構 規則引擎 quartz架構quartz
- Drools規則引擎簡介
- Drools 規則引擎應用
- 決策表模式: 一種業務規則引擎實現方式模式
- 使用DDD規格Specification模式構建資料驅動規則引擎 - jonblankenship模式
- Java中最流行的幾種業務規則引擎簡介Java
- 【java規則引擎】drools6.5.0中kie的概論Java
- WebSphere ILOG JRules 規則引擎執行模式簡介Web模式
- Evrete 規則引擎簡介 | baeldungVR
- 【java規則引擎】之Drools引擎中模擬ReteooStatefulSession內部設計結構JavaSession
- j-easy/easy-rules: Java簡單的規則引擎Java
- 【java規則引擎】drools6.5.0版本api簡介JavaAPI
- make的模式規則模式
- Drools 業務規則引擎的完整教程
- 規則引擎Golang指南 – Mohit KhareGolang
- 快速整合和使用 drools 規則引擎
- 【java規則引擎】基本語法和相關屬性介紹Java
- ZT - WebSphere ILOG JRules 規則引擎執行模式簡介(4)Web模式
- ZT - WebSphere ILOG JRules 規則引擎執行模式簡介(3)Web模式
- ZT - WebSphere ILOG JRules 規則引擎執行模式簡介(2)Web模式