在軟體開發中,我們經常需要應用一組規則或條件來過濾和處理資料。使用傳統的 if 和 else 條件管理這些規則可能會變得繁瑣且難以維護。規則引擎提供了一種更靈活、更有條理的方法來定義和執行這些規則。在本文中,我們將探討如何使用 Java 函數語言程式設計原理在 Spring Boot 專案中構建一個簡單的規則引擎。
什麼是規則引擎?
規則引擎是一個專家系統程式,它對輸入資料執行規則,如果任何條件匹配,則執行相應的操作。
規則引擎負責管理一組規則,並將它們應用於一組物件。它根據定義的規則過濾物件並返回過濾結果。
案例
在這個應用程式中,首先我將建立一個UserController.java類並建立一個返回使用者列表的Rest端點。
import com.example.spring_boot_rule_engine_demo.model.User; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.GetMapping; import java.util.ArrayList; import java.util.List;
@RestController @RequestMapping(<font>"/user") public class UserController { @GetMapping public List<User> getAllUser(){ return userData(); }
private List<User> userData() { List<User> users = new ArrayList<>(); User user1 = new User("sumit", 33); User user2 = new User("agam", 13); User user3 = new User("mohit", 23); User user4 = new User("kailash", 43); users.add(user1); users.add(user2); users.add(user3); users.add(user4); return users; }
}
|
現在,我們要求只獲取年齡大於 30 歲、姓名以 sum 開頭的使用者。
因此,現在我們需要建立兩條規則,並在向客戶端返回響應前應用這兩條規則。定義規則:
首先,我們將使用一個名為 Rule 的列舉來定義規則。列舉中的每條規則都代表我們要評估的特定條件或標準。
import com.example.spring_boot_rule_engine_demo.model.User;
import java.util.function.Predicate;
public enum Rule implements TestRule {
AGE_GREATER_THAN_30(user -> user.getAge() > 30), NAME_STARTS_WITH_SUM(user -> user.getName().startsWith(<font>"sum"));
private final Predicate<User> predicate;
Rule(Predicate<User> predicate) { this.predicate = predicate; }
public Predicate<User> getPredicate() { return predicate; } }
|
讓我建立一個 TestRule 介面來定義不需要實現的方法。
import java.util.function.Predicate;
public interface TestRule { <T> Predicate<T> getPredicate(); }
|
建立自己的規則引擎:
接下來,我們建立 RuleEngine 類。該類將處理規則的管理和執行。它維護一個規則列表,並提供新增新規則和根據這些規則過濾物件的方法。
實現過濾邏輯
在 RuleEngine 類的過濾方法中,我們遍歷物件列表,並使用 Java 8 Stream API 中的 allMatch 方法應用每條規則。該方法會檢查給定物件是否透過了所有規則。如果所有規則都透過,我們就會將該物件新增到過濾列表中。
import com.example.spring_boot_rule_engine_demo.rule.TestRule;
import java.util.ArrayList; import java.util.List;
public class RuleEngine<T> { private List<TestRule> rules;
public RuleEngine() { this.rules = new ArrayList<>(); }
public void addRule(TestRule rule) { rules.add(rule); }
public List<T> filter(List<T> items) { List<T> filteredItems = new ArrayList<>(); for (T item : items) { if (rules.stream().allMatch(rule -> rule.getPredicate().test(item))) { filteredItems.add(item); } } return filteredItems; } } public class User {
private String name; private int age;
public User(String name, int age) { this.name = name; this.age = age; }
public User() {
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; } }
|
在 UserController.java 類中建立的獲取所有使用者 API 中,我們演示了規則引擎的用法。我們建立了一個使用者物件列表,並用兩條規則初始化了規則引擎:AGE_GREATER_THAN_30 和 NAME_STARTS_WITH_SUM。然後,我們呼叫規則引擎的過濾器方法,並傳遞使用者物件列表。規則引擎會對每個使用者應用規則,並返回過濾後的列表。
最後,我們遍歷過濾後的列表,返回符合指定規則的使用者列表。
import com.example.spring_boot_rule_engine_demo.engine.RuleEngine; import com.example.spring_boot_rule_engine_demo.model.User; import com.example.spring_boot_rule_engine_demo.rule.Rule; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.GetMapping; import java.util.ArrayList; import java.util.List;
@RestController @RequestMapping(<font>"/user") public class UserController { @GetMapping public List<User> getAllUser(){ RuleEngine<User> ruleEngine = new RuleEngine<>(); ruleEngine.addRule(Rule.AGE_GREATER_THAN_30); ruleEngine.addRule(Rule.NAME_STARTS_WITH_SUM); List<User> filteredUser = ruleEngine.filter(userData()); return filteredUser; }
private List<User> userData() { List<User> users = new ArrayList<>(); User user1 = new User("sumit", 33); User user2 = new User("agam", 13); User user3 = new User("mohit", 23); User user4 = new User("kailash", 43); users.add(user1); users.add(user2); users.add(user3); users.add(user4); return users; }
}
|
原始碼:Github