接触过Drools的同学都会被复杂的Api给难住,简直就是入门到放弃的一个过程,而EasyRule就是Drools的简化版,裁剪了部分使用场景非常少的复杂功能,也简化了很多Drools中的组件,这样我们在使用EasyRule的时候对于API理解就非常容易了
Easy Rules是一个简单的JAVA开源规则引擎,它提供了规则抽象来创建带有评估条件和执行操作的规则,规则引擎API通过运行一组规则以评估条件和执行操作。
定义规则
注解方式定义规则:
@Rule(name = "weather rule", description = "if it rains then take an umbrella" )
public class WeatherRule {
@Condition
public boolean itRains(@Fact("rain") boolean rain) {
return rain;
}
@Action
public void takeAnUmbrella() {
System.out.println("It rains, take an umbrella!");
}
}
流式编程方式定义规则:
Rule weatherRule = new RuleBuilder()
.name("weather rule")
.description("if it rains then take an umbrella")
.when(facts -> facts.get("rain").equals(true))
.then(facts -> System.out.println("It rains, take an umbrella!"))
.build();
表达式方式定义规则:
Rule weatherRule = new MVELRule()
.name("weather rule")
.description("if it rains then take an umbrella")
.when("rain == true")
.then("System.out.println(\"It rains, take an umbrella!\");");
yml文件方式定义规则:
name: "weather rule"
description: "if it rains then take an umbrella"
condition: "rain == true"
actions:
- "System.out.println(\"It rains, take an umbrella!\");"
Rule weatherRule = MVELRuleFactory.createRuleFrom(new File("weather-rule.yml"));
执行规则:
public class Test {
public static void main(String[] args) {
// define facts
Facts facts = new Facts();
facts.put("rain", true);
// define rules
Rule weatherRule = ...
Rules rules = new Rules();
rules.register(weatherRule);
// fire rules on known facts
RulesEngine rulesEngine = new DefaultRulesEngine();
rulesEngine.fire(rules, facts);
}
}
场景说明:
假设我们有这样一个场景:
不使用规则引擎实现:
public class FizzBuzzMain {
public static void main(String[] args) {
for(int i = 1; i <= 100; i++) {
if (((i % 5) == 0) && ((i % 7) == 0))
System.out.print("fizzbuzz");
else if ((i % 5) == 0) System.out.print("fizz");
else if ((i % 7) == 0) System.out.print("buzz");
else System.out.print(i);
System.out.println();
}
System.out.println();
}
}
使用Easy Rules实现:
1. 引入依赖
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-core</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-support</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-mvel</artifactId>
<version>3.2.0</version>
</dependency>
2. 使用注解方式定义规则:
2.1 定义规则:
public class RuleClass {
@Rule(priority = 1)
public static class FizzRule {
@Condition
public boolean isFizz(@Fact("number") int number) {
return number % 5 == 0;
}
@Action
public void printFizz() {
System.out.print("fizz");
}
}
@Rule(priority = 2)
public static class BuzzRule {
@Condition
public boolean isBuzz(@Fact("number") int number) {
return number % 7 == 0;
}
@Action
public void printBuzz() {
System.out.print("buzz");
}
}
public static class FizzBuzzRule extends UnitRuleGroup {
public FizzBuzzRule(Object... rules) {
for (Object rule : rules) {
addRule(rule);
}
}
@Override
public int getPriority() {
return 0;
}
}
@Rule(priority = 3)
public static class NonFizzBuzzRule {
@Condition
public boolean isNotFizzNorBuzz(@Fact("number") int number) {
return number % 5 != 0 || number % 7 != 0;
}
@Action
public void printInput(@Fact("number") int number) {
System.out.print(number);
}
}
}
2.2 客户端调用:
public class FizzBuzzMainWithRule {
public static void main(String[] args) {
// create a rules engine
RulesEngineParameters parameters = new RulesEngineParameters().skipOnFirstAppliedRule(true);
RulesEngine fizzBuzzEngine = new DefaultRulesEngine(parameters);
// create rules
Rules rules = new Rules();
rules.register(new FizzRule());
rules.register(new BuzzRule());
rules.register(new FizzBuzzRule(new FizzRule(), new BuzzRule()));
rules.register(new NonFizzBuzzRule());
// fire rules
Facts facts = new Facts();
for (int i = 1; i <= 100; i++) {
facts.put("number", i);
fizzBuzzEngine.fire(rules, facts);
System.out.println();
}
}
}
3. 使用yml文件定义规则:
3.1 定义规则:
---
name: "fizz rule"
description: "print fizz if the number is multiple of 5"
priority: 1
condition: "number % 5 == 0"
actions:
- "System.out.println(\"fizz\")"
---
name: "buzz rule"
description: "print buzz if the number is multiple of 7"
priority: 2
condition: "number % 7 == 0"
actions:
- "System.out.println(\"buzz\")"
---
name: "fizzbuzz rule"
description: "print fizzbuzz if the number is multiple of 5 and 7"
priority: 0
condition: "number % 5 == 0 && number % 7 == 0"
actions:
- "System.out.println(\"fizzbuzz\")"
---
name: "non fizzbuzz rule"
description: "print the number itself otherwise"
priority: 3
condition: "number % 5 != 0 || number % 7 != 0"
actions:
- "System.out.println(number)"
3.2 客户端调用:
public class FizzBuzzMainWithYmlRule {
public static void main(String[] args) throws FileNotFoundException {
// create a rules engine
RulesEngineParameters parameters = new RulesEngineParameters().skipOnFirstAppliedRule(true);
RulesEngine fizzBuzzEngine = new DefaultRulesEngine(parameters);
// create rules
String filePath = System.getProperty("user.dir") + "/src/main/resources/easyrules/fizzbuzz/rule.yml";
Rules rules = MVELRuleFactory.createRulesFrom(new FileReader(filePath));
// fire rules
Facts facts = new Facts();
for (int i = 1; i <= 100; i++) {
facts.put("number", i);
fizzBuzzEngine.fire(rules, facts);
System.out.println();
}
}
}