当前位置: 首页 > 工具软件 > Easy Rules > 使用案例 >

easy rules java实例_规则引擎 Easy Rules 使用实例(一)

郭麒
2023-12-01

简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

语言: java

依赖:

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、不使用规则引擎的实现方式:

public class FizzBuzz {

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();

}

}

2、将规则存放在 .java 文件中:

(1).java 规则文件内容如下:

public class RuleClass {

@Rule(priority = 1)

public static class FizzRule {

@Condition

public boolean isFizz(@Fact("number") Integer 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") Integer 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") 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

相关文档

 类似资料: