org.jeasy
easy-rules-core
3.2.0
org.jeasy
easy-rules-support
3.2.0
org.jeasy
easy-rules-mvel
3.2.0
一、使用场景
在编写代码的过程中,我们对if.else .语句相当了解。 但是,如果在十几个、几十个、一百个甚至更多条件分支的情况下,坚持在业务逻辑代码中使用if.else .语句,则此文件中的代码会非常不协调。 另外,如果以后想添加或删除规则,则必须来此业务逻辑代码修改if.else .语句。 这对未来的维护有一定的影响
针对这种情况,可以考虑使用规则引擎来解决。 有多个规则引擎。 本文介绍了easy rule规则引擎的使用。 对于以上场景,easy rule从业务逻辑代码中提取if.else .的逻辑,并将这些逻辑存储在单独的文件中。 这样做,业务逻辑的代码看起来很清晰。 另外,将来想修改这些规则的话,直接查找存储这些规则的文件就可以了。 easy rule有两种方法:使用. java文件和使用. yml文件。 分别说明。
二、使用案例
假设有这样的场景:
)1)一个数字能被5整除时,输出“fizz”。
)2)一个数字能被7整除时,输出“buzz”。
)3)一个数字同时被5和7整除时,输出" fizzbuzz "。
)4)如果一个数字不满足上述三个条件,则输出该数字本身。
1、不使用规则引擎的实现方式:
公共类fizzbuzz {
publicstaticvoidmain (字符串[ ] args ) {
for(intI=1; i=100; I ) {
if () (I%5)==0) ) (i % 7)==0) )
system.out.print(fizzbuzz );
elseif () I%5)==0) system.out.print('fizz );
elseif () I%7)==0) system.out.print ) ' buzz ';
ELSEsystem.out.print(I;
System.out.println (;
}
System.out.println (;
}
}
2 .将规则存储在. java文件中:
(1).java规则文件的内容如下。
公共类规则类{
@ rule (优先级=1) )。
公共静态类fizz rule {
@Condition
publicbooleanisfizz (@ fact (' number ) )集成器{
返回编号%5==0;
}
@Action
公共语音打印过滤器(
system.out.print('fizz ';
}
}
@ rule (优先级=2) )
公共静态类buzzrule {
@Condition
publicbooleanisbuzz (@ fact (' number ) )。
返回编号%7==0;
}
@Action
公共语音打印buzz (
system.out.print('buzz ';
}
}
publicstaticclassfizzbuzzruleextendsunitrulegroup {
publicfizzbuzzrule (object . rules ) {
对象规则:规则(for ) {
添加规则(rule );
}
}
@Override
公共插入获取优先级
返回0;
}
}
@ rule (优先级=3) )
publicstaticclassnonfizzbuzzrule {
@Condition
公共布尔is not fiz
zNorBuzz(@Fact("number") Integer number) {// can return true, because this is the latest rule to trigger according to
// assigned priorities
// and in which case, the number is not fizz nor buzz
return number % 5 != 0 || number % 7 != 0;
}
@Action
public void printInput(@Fact("number") Integer number) {
System.out.print(number);
}
}
}
(2)客户端调用代码如下:
public class RuleClient {
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 RuleClass.FizzBuzzRule(new RuleClass.FizzRule(), new RuleClass.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();
}
}
}
代码注解:
注解1
RulesEngineParameters parameters = new RulesEngineParameters().skipOnFirstAppliedRule(true);
这行代码的作用是为接下来的RulesEngine的创建设置属性。这里只设置了一个属性skipOnFirstAppliedRule,意思是在之后执行RuleClass中的规则时,只要有一个规则被触发,则当前被传进来的Fact就不再判断是否满足其他规则的条件。
像这样的属性还有几个,我们在接下来的文章中将会讲到。
注解2
我们要注意Facts的使用。Facts的用法很像Map,它是客户端和规则文件之间通信的桥梁。在客户端使用put方法向Facts中添加数据,在规则文件中通过key来得到相应的数据。
3、将规则文件存放在 .yml 文件中:
(1).yml 规则文件内容如下:
---
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)"
(2)客户端调用代码如下:
public class RuleClient {
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
Rules rules = MVELRuleFactory.createRulesFrom(new FileReader("fizzbuzz.yml"));
// fire rules
Facts facts = new Facts();
for (int i = 1; i <= 100; i++) {
facts.put("number", i);
fizzBuzzEngine.fire(rules, facts);
System.out.println();
}
}
}
执行结果如下:
1
2
3
4
fizz
6
buzz
8
9
fizz
11
12
13
buzz
fizz
16
17
18
19
fizz
buzz
22
23
24
fizz
26
27
buzz
29
fizz
31
32
33
34
fizzbuzz
36
37
38
39
fizz
41
buzz
43
44
fizz
46
47
48
buzz
fizz
51
52
53
54
fizz
buzz
57
58
59
fizz
61
62
buzz
64
fizz
66
67
68
69
fizzbuzz
71
72
73
74
fizz
76
buzz
78
79
fizz
81
82
83
buzz
fizz
86
87
88
89
fizz
buzz
92
93
94
fizz
96
97
buzz
99
fizz
相关文档