Easy Rules
是一個輕量級且易于使用的規則引擎,適用于Java應用。下面是一個簡單的示例,演示如何使用 Easy Rules
定義和執行規則。
添加依賴
首先,在你的Java項目中添加 Easy Rules 的 Maven 依賴(如果你使用的是Maven構建工具):
<dependency><groupId>org.jeasy</groupId><artifactId>easy-rules-core</artifactId><version>4.3.0</version> <!-- 確保檢查最新版本 -->
</dependency>
簡單案例
創建規則
接下來,定義一個簡單的規則。假設我們有一個業務需求:如果一個人的年齡大于18歲,則認為這個人是成年人。
import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Fact;
import org.jeasy.rules.annotation.Rule;@Rule(name = "adult rule", description = "if person's age is greater than 18 then he is an adult")
public class AdultRule {@Conditionpublic boolean check(@Fact("age") int age) {return age > 18;}@Actionpublic void execute() throws Exception {System.out.println("You are an adult.");}
}
執行規則
然后,創建一個簡單的應用程序來執行這些規則:
import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.api.RulesEngine;
import org.jeasy.rules.core.DefaultRulesEngine;public class Application {public static void main(String[] args) {// Create factsFacts facts = new Facts();facts.put("age", 20); // 假設這個人的年齡是20歲// Create rulesRules rules = new Rules();rules.register(new AdultRule());// Create a rules engine and fire rules on known factsRulesEngine rulesEngine = new DefaultRulesEngine();rulesEngine.fire(rules, facts);}
}
在這個例子中,我們首先創建了一些事實(Facts),即這里的人的年齡為20歲。接著,我們定義了一個規則(AdultRule),該規則根據年齡判斷是否為成年人。最后,我們使用 DefaultRulesEngine
來觸發規則,并基于提供的事實進行評估。
當你運行上述代碼時,應該會在控制臺看到輸出:“You are an adult.” 這表明規則已經成功執行并得出結論。
通過這種方式,你可以輕松地在自己的項目中集成和使用 Easy Rules
來處理各種業務邏輯。它不僅簡化了規則的定義過程,還使得維護和更新規則變得更為直觀和直接。
當然,下面是一個更復雜的 Easy Rules
使用案例,模擬一個電商場景中的訂單處理系統。在這個案例中,我們將根據訂單金額、用戶等級和促銷活動來決定是否應用折扣、是否免運費,以及是否需要額外的審核。
復雜案例
場景描述
- 用戶等級:普通用戶(regular)、VIP 用戶(vip)
- 訂單金額:大于 100 元可以免運費
- 促銷活動:如果當前有促銷活動,所有訂單享受 10% 折扣
- VIP 用戶:額外享受 5% 折扣
- 高價值訂單:訂單金額超過 500 元,需要額外審核
1. 定義事實類(Facts)
// Order.java
public class Order {private double amount;private String userLevel; // "regular" or "vip"private boolean isPromotionActive;private boolean isFreeShipping;private double finalAmount;private boolean requiresReview;// 構造函數public Order(double amount, String userLevel, boolean isPromotionActive) {this.amount = amount;this.userLevel = userLevel;this.isPromotionActive = isPromotionActive;this.finalAmount = amount;this.isFreeShipping = false;this.requiresReview = false;}// Getter 和 Setter 方法public double getAmount() { return amount; }public String getUserLevel() { return userLevel; }public boolean isPromotionActive() { return isPromotionActive; }public boolean isFreeShipping() { return isFreeShipping; }public void setFreeShipping(boolean freeShipping) { this.isFreeShipping = freeShipping; }public double getFinalAmount() { return finalAmount; }public void setFinalAmount(double finalAmount) { this.finalAmount = finalAmount; }public boolean isRequiresReview() { return requiresReview; }public void setRequiresReview(boolean requiresReview) { this.requiresReview = requiresReview; }@Overridepublic String toString() {return "Order{" +"amount=" + amount +", userLevel='" + userLevel + '\'' +", isPromotionActive=" + isPromotionActive +", isFreeShipping=" + isFreeShipping +", finalAmount=" + finalAmount +", requiresReview=" + requiresReview +'}';}
}
2. 定義多個規則
規則 1:免運費規則
import org.jeasy.rules.annotation.*;
import org.jeasy.rules.api.Facts;@Rule(name = "Free Shipping Rule", priority = 3)
public class FreeShippingRule {@Conditionpublic boolean isEligibleForFreeShipping(@Fact("order") Order order) {return order.getAmount() > 100;}@Actionpublic void applyFreeShipping(@Fact("order") Order order) {order.setFreeShipping(true);System.out.println("免運費已應用:訂單金額 > 100元");}
}
規則 2:促銷折扣規則
@Rule(name = "Promotion Discount Rule", priority = 2)
public class PromotionDiscountRule {@Conditionpublic boolean isPromotionActive(@Fact("order") Order order) {return order.isPromotionActive();}@Actionpublic void applyPromotionDiscount(@Fact("order") Order order) {double discount = order.getFinalAmount() * 0.10;order.setFinalAmount(order.getFinalAmount() - discount);System.out.println("促銷折扣 10% 已應用");}
}
規則 3:VIP 用戶額外折扣
@Rule(name = "VIP Discount Rule", priority = 1)
public class VipDiscountRule {@Conditionpublic boolean isVipUser(@Fact("order") Order order) {return "vip".equalsIgnoreCase(order.getUserLevel());}@Actionpublic void applyVipDiscount(@Fact("order") Order order) {double discount = order.getFinalAmount() * 0.05;order.setFinalAmount(order.getFinalAmount() - discount);System.out.println("VIP 用戶額外 5% 折扣已應用");}
}
規則 4:高價值訂單審核規則
@Rule(name = "High Value Order Review Rule", priority = 0)
public class HighValueOrderReviewRule {@Conditionpublic boolean isHighValueOrder(@Fact("order") Order order) {return order.getAmount() > 500;}@Actionpublic void flagForReview(@Fact("order") Order order) {order.setRequiresReview(true);System.out.println("高價值訂單,需人工審核");}
}
3. 主程序執行規則
import org.jeasy.rules.api.*;
import org.jeasy.rules.core.DefaultRulesEngine;public class OrderProcessingExample {public static void main(String[] args) {// 創建訂單事實Order order = new Order(550.0, "vip", true); // 金額550,VIP用戶,促銷中Facts facts = new Facts();facts.put("order", order);// 注冊所有規則Rules rules = new Rules();rules.register(new FreeShippingRule());rules.register(new PromotionDiscountRule());rules.register(new VipDiscountRule());rules.register(new HighValueOrderReviewRule());// 創建規則引擎并執行RulesEngine rulesEngine = new DefaultRulesEngine();rulesEngine.fire(rules, facts);// 輸出最終訂單狀態System.out.println("\n最終訂單信息:");System.out.println(order);}
}
4. 運行結果輸出
免運費已應用:訂單金額 > 100元
促銷折扣 10% 已應用
VIP 用戶額外 5% 折扣已應用
高價值訂單,需人工審核最終訂單信息:
Order{amount=550.0, userLevel='vip', isPromotionActive=true, isFreeShipping=true, finalAmount=467.5, requiresReview=true}
說明
- 優先級(priority):數值越小,優先級越高。例如,高價值訂單審核規則最后執行,但優先級最高(0),確保它在所有計算后仍能被觸發。
- 規則解耦:每個規則獨立,易于維護和測試。
- 可擴展性:你可以輕松添加新規則,如“節假日雙倍積分”、“地區限制”等。
這個案例展示了 Easy Rules
如何處理多條件、多動作的復雜業務邏輯,同時保持代碼清晰和可維護性。非常適合中小型系統中實現靈活的業務規則管理。