我们在写业务代码经常遇到需要一大堆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
      <dependency><groupId>org.jeasy</groupId><artifactId>easy-rules-core</artifactId><version>3.4.0</version></dependency><dependency><groupId>org.jeasy</groupId><artifactId>easy-rules-mvel</artifactId><version>3.4.0</version></dependency>
  • 编写规则POJO:
@Rule(name = "被3整除", description = "number如果被3整除,打印:number is three")
public class ThreeRule {  @Condition //条件判断注解:如果return true, 执行Actionpublic boolean isThree(@Fact("number") int number){return number % 3 == 0;}@Action //执行方法注解public void threeAction(@Fact("number") int number){System.out.print(number + " is three");}@Priority //优先级注解:return 数值越小,优先级越高public int getPriority(){return 1;}
}
@Rule(name = "被8整除")
public class EightRule {@Conditionpublic boolean isEight(@Fact("number") int number){return number % 8 == 0;}@Actionpublic void eightAction(@Fact("number") int number){System.out.print(number + " is eight");}@Prioritypublic int getPriority(){return 2;}
}
@Rule(name = "被3和8同时整除",  description = "这是一个组合规则")
public class ThreeEightRuleUnitGroup extends UnitRuleGroup {  public ThreeEightRuleUnitGroup(Object... rules) {for (Object rule : rules) {addRule(rule);}}@Overridepublic int getPriority() {return 0;}
}
@Rule(name = "既不被3整除也不被8整除", description = "打印number自己")
public class OtherRule {  @Conditionpublic boolean isOther(@Fact("number") int number){return number % 3 != 0 || number % 8 != 0;}@Actionpublic void printSelf(@Fact("number") int number){System.out.print(number);}@Prioritypublic 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();}}
}
  • 我们可以得到执行结果
1
2
3 is three
4
5
6 is three
7
8 is eight
9 is three
10
11
12 is three
13
14
15 is three
16 is eight
17
18 is three
19
20
21 is three
22
23
24 is three24 is eight
25
26
27 is three
28
29
30 is three
31
32 is eight
33 is three
34
35
36 is three
37
38
39 is three
40 is eight
41
42 is three
43
44
45 is three
46
47
48 is three48 is eight
49
50

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

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

public class Person {  private String name;private boolean adult;private int age;//getter, setter 省略
}

我们定义两个规则:

  • 规则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 allowed 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", 14);Facts facts = new Facts();facts.put("person", tom);//创建规则1Rule 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);");//创建规则2Rule alcoholRule = MVELRuleFactory.createRuleFrom(new FileReader("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);}
}

Easy-rules使用介绍相关推荐

  1. 常见的规则引擎(Drools,RuleBook,Easy Rules等)对比

    参考文章: https://www.jianshu.com/p/96cd60059aae 规则引擎调研 - 人在江湖之诗和远方 - 博客园 java开源规则引擎比较_常用规则引擎比较分析_学校砍了我的 ...

  2. Java规则引擎easy rules

    场景 简单点描述,有点策略模式的味道,所以可以处理if-else-语句; 其核心内容还是在规则引擎,所以和Drools规则类似,目前支持MVEL和SpEL表达式,配置外置; 最后支持各种规则的组合,支 ...

  3. 规则引擎----easy rules

    一.规则引擎的作用 将复杂的if else判断剥离出来 二.使用 2.1.引入POM <!--easy rules核心库--><dependency><groupId&g ...

  4. java 实现规则引擎_Java规则引擎 Easy Rules

    1.  Easy Rules 概述 Easy Rules是一个Java规则引擎,灵感来自一篇名为<Should I use a Rules Engine?>的文章 规则引擎就是提供一种可选 ...

  5. 【转】什么是规则引擎(Drools、OpenL Tablets、Easy Rules、RuleBook)

    什么是规则引擎(Drools.OpenL Tablets.Easy Rules.RuleBook) 发表于:2021年1月23日 分类:Drools, 规则引擎 标签:Drools, Easy-Rul ...

  6. linux profiling 工具,高性能:LEP (LINUX EASY PROFILING) 工具介绍

    LEP工具入门 给大家推荐个宋宝华老师出品的小工具 相关文档: LEP的介绍,大家直接看上面的文档即可. 下面是我记录的安装部署过程 环境:CentOS7.7 IP: 10.10.11.11 安装le ...

  7. dnd 辅助 android,Easy DND

    Easy DND更加简洁直观的勿扰模式设计,不同于系统所自带的勿扰模式,在这款软件当中你可以在特定的场景进行设置勿扰模式,不会因为勿扰模式而耽误某些较为重大的事情,而且这款软件操作起来更加的简单方便, ...

  8. linux localtime 线程安全,LocalDate、LocalTime、LocalDateTime常用方法介绍(线程安全)...

    一.JDK Release Notes: https://www.oracle.com/technetwork/java/javase/jdk-relnotes-index-2162236.html? ...

  9. 怎样在c语言程序里面添加图片,C语言 使用图形库(Easy X)绘制界面及程序添加音乐...

    Easy X 图形库介绍 Easy X EasyX 是针对 C++ 的图形库,可以帮助 C++语言初学者快速上手图形和游戏编程. 比如,可以用 VC + EasyX 很快的用几何图形画一个房子,或者一 ...

  10. 学习记录EasyTouch:Easy Joystick

    Easy Joystick相关介绍: Easy Joystick包含4个部分 Joystick properties:用于控制操纵杆的属性 Joystick name:用于修改操纵杆的名称 Enabl ...

最新文章

  1. 打造精简版Linux-mini
  2. MySQL面试三连杀:如何实现可重复读、又为什么会出现幻读、是否解决了幻读问题?...
  3. 在ListBox中添加ToggleButton(有IsChecked属性)
  4. linux之cal命令详解,linux命令大全之cal命令详解(显示日历)
  5. Linux下的零拷贝
  6. 计算道路超高lisp_5G+AI超高清智能视频监控将迎来增长期
  7. 有源光缆AOC在40G网络布线中备受欢迎的主要原因
  8. java和ajax超时_java – 如何在不重置tomcat的会话超时的情况下执行经过身份验证的AJAX请求?...
  9. 作业MathExam
  10. leetCode 41.First Missing Positive (第一个丢失的正数) 解题思路和方法
  11. 回溯---含有相同元素求子集
  12. wm java 载入jad错误_jad文件的错误代码,分享
  13. clodop 打印插件打印不显示问题
  14. 我常用的Windows软件
  15. 2023东华大学计算机考研信息汇总
  16. Microsoft Teams网络慢,卡顿,怎么办?
  17. 2021-09-21如何在PCB上做一个城市地铁图?
  18. adlds文件服务器,AD LDS管理工具入门攻略
  19. caj转pdf——包含下载链接
  20. 企业该分多少钱给员工?看柏明顿阿米巴奖金分配方案

热门文章

  1. 24. 使用GitHub
  2. LoadRunner测试一个简单的AJAX例子
  3. Python3-问题整理
  4. 应用安全-Web安全-越权漏洞整理
  5. Base64,DES,RSA,SHA1,MD5 笔记
  6. 高性能极致用户体验前端开发实战
  7. centos7下发邮件给自己的QQ邮箱
  8. CentOS 上MySQL报错Can't connect to local Mysql server through socket '/tmp/mysql.scok' (111)
  9. iOS 性能优化:Instruments 工具的救命三招
  10. .net将html转换PDF