java轻量级规则引擎easy

网友投稿 465 2022-12-04


java轻量级规则引擎easy

轻量级规则引擎easy-rules--参考

我们在写业务代码经常遇到需要一大堆if/else,会导致代码可读性大大降低,有没有一种方法可以避免代码中出现大量的判断语句呢?答案是用规则引擎,但是传统的规则引擎都比较重,比如开源的Drools,不适合在小需求中应用。最近在github上面看到一个傻瓜式的java规则引擎Easy-Rules,这里结合自己写的demo介绍如何使用这个规则引擎,希望对大家有所帮助。

easy-rules的特点

轻量级类库和容易上手

基于POJO的开发与注解的编程模型

基于MVEL表达式的编程模型(适用于极简单的规则,一般不推荐)

支持根据简单的规则创建组合规则

方便且适用于java的抽象的业务模型规则

它主要包括几个主要的类或接口:Rule,RulesEngine,RuleListener,Facts还有几个主要的注解:@Action,@Condition,@Fact,@Priority,@Rule

例1:基于POJO开发与注解的编程模型:判断1-50中,被3或者8整除的数

首先maven 引入easy-rules

org.jeasy

easy-rules-core

3.3.0

org.jeasy

easy-rules-mvel

3.3.0

编写规则POJO:

规则1

@Rule(name = "被3整除", description = "number如果被3整除,打印:number is three")

public class ThreeRule {

/**

* Condition:条件判断注解:如果return true, 执行Action

*

* @param number

* @return

*/

@Condition

public boolean isThree(@Fact("number") int number) {

return number % 3 == 0;

}

/**

* Action 执行方法注解

*

* @param number

*/

@Action

public void threeAction(@Fact("number") int number) {

System.out.println(number + " is three");

}

/**

* Priority:优先级注解:return 数值越小,优先级越高

*

* @return

*/

@Priority

public int getPriority() {

return 1;

}

}

规则2

@Rule(name = "被8整除")

public class EightRule {

/**

* 条件

*

* @param number

* @return

*/

@Condition

public boolean isEight(@Fact("number") int number) {

return number % 8 == 0;

}

/**

* 满足条件的动作

*

* @param number

*/

@Action

public void eightAction(@Fact("number") int number) {

System.out.println(number + " is eight");

}

/**

* 条件判断的优先级

*

* @return

*/

@Priority

public int getPriority() {

return 2;

}

}

规则3(组合规则-同时执行)

@Rule(name = "被3和8同时整除", description = "这是一个组合规则")

public class ThreeEightRuleUnitGroup extends UnitRuleGroup {

public ThreeEightRuleUnitGroup(Object... rules) {

for (Object rule : rules) {

addRule(rule);

}

}

@Override

public int getPriority() {

return 0;

}

}

规则4

@Rule(name = "既不被3整除也不被8整除", description = "打印number自己")

public class OtherRule {

@Condition

public boolean isOther(@Fact("number") int number){

return number % 3 != 0 || number % 8 != 0;

}

@Action

public void printSelf(@Fact("number") int number){

System.out.print(number);

}

@Priority

public int getPriority(){

return 3;

}

}

执行规则

public class ThreeEightRuleLauncher {

public static void main(String[] args) {

/**

* 创建规则执行引擎

* 注意: skipOnFirstAppliedRule意思是,只要匹配到第一条规则就跳过后面规则匹配

*/

RulesEngineParameters parameters = new

RulesEngineParameters().skipOnFirstAppliedRule(true);

RulesEngine rulesEngine = new DefaultRulesEngine(parameters);

//创建规则

Rules rules = new Rules();

rules.register(new EightRule());

rules.register(new ThreeRule());

rules.register(new ThreeEightRuleUnitGroup(new EightRule(), new ThreeRule()));

rules.register(new OtherRule());

Facts facts = new Facts();

for (int i=1 ; i<=50 ; i++){

//规则因素,对应的name,要和规则里面的@Fact 一致

facts.put("number", i);

//执行规则

rulesEngine.fire(rules, facts);

System.out.println();

}

}

}

例2:基于MVEL表达式的编程模型

本例演示如何使用MVEL表达式定义规则,MVEL通过Easy-Rules MVEL模块提供。此模块包含使用MVEL定义规则的API。我们将在这里使用这些API,其目标是实现一个简单的商店应用程序,要求如下:禁止儿童购买酒精,成年人的最低法定年龄为18岁。 商店顾客由Person类定义:

@Data

@AllArgsConstructor

@NoArgsConstructor

public class Person {

private String name;

private boolean adult;

private int age;

//getter, setter 省略

public Person(String name, int age) {

this.name = name;

this.age = age;

}

}

我们定义两个规则:

规则1:可以更新Person实例,判断年龄是否大于18岁,并设置成人标志。

规则2:判断此人是否为成年人,并拒绝儿童(即非成年人)购买酒精。

显然,规则1的优先级要大于规则2,我们可以设置规则1的Priority为1,规则2的Priority为2,这样保证规则引擎在执行规则的时候,按优先级的顺序执行规则。

规则1的定义

Rule ageRule = new MVELRule()

.name("age rule")

.description("Check if person's age is > 18 and marks the person as adult")

.priority(1)

.when("person.age > 18")

.then("person.setAdult(true);");

规则2的定义,我们放到alcohol-rule.yml文件中

name: "alcohol rule"

description: "children are not ahttp://llowed to buy alcohol"

priority: 2

condition: "person.isAdult() == false"

actions:

- "System.out.println(\"Shop: Sorry, you are not allowed to buy alcohol\");"

执行规则

public class ShopLauncher {

public static void main(String[] args) throws Exception {

//创建一个Person实例(Fact)

Person tom = new Person("Tom", 19);

Facts facts = new Facts();

facts.put("person", tom);

//创建规则1

Rule ageRule = new MVELRule()

.name("age rule")

.description("Check if person's age is > 18 and marks the person as adult")

.priority(1)

.when("person.age > 18")

.then("person.setAdult(true);");

//创建规则2

Rule alcoholRule = new MVELRuleFactory(new YamlRuleDefinitionReader()).

createRule(new FileReader(Reshttp://ourceUtils.getFile("classpath:alcohol-rule.yml")));

Rules rules = new Rules();

rules.register(ageRule);

rules.register(alcoholRule);

//创建规则执行引擎,并执行规则

RulesEngine rulesEngine = new DefaultRulesEngine();

System.out.println("Tom: Hi! can I have some Vodka please?");

rulesEngine.fire(rules, facts);

System.out.println(jsON.toJSONString(tom));

}

}

执行结果如下:

本篇主要介绍easy-rules的使用

深入了解原理,可以查看github源码:https://github.com/j-easy/easy-rules


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Spring boot文件路径映射配置代码实例
下一篇:Spring boot使用logback实现日志管理过程详解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~