Java规则引擎——EasyRules的使用实例
一、easy-rule使用的几种方式:
1、直接在代码中写规则
package org.songdan.easy.rules.anno; import org.jeasy.rules.api.Facts; import org.jeasy.rules.api.Rules; import org.jeasy.rules.api.RulesEngine; import org.jeasy.rules.core.DefaultRulesEngine; import org.jeasy.rules.core.RulesEngineParameters; /** * @author coco_xu * @date 2020-04-16 */ 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 RuleClass.FizzRule()); rules.register(new RuleClass.BuzzRule()); rules.register(new RuleClass.FizzBuzzRule(new RuleClass.FizzRule(), new RuleClass.BuzzRule())); rules.register(new RuleClass.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(); } } }
2、
package org.songdan.easy.rules.fluent; import org.jeasy.rules.api.*; import org.jeasy.rules.core.DefaultRulesEngine; import org.jeasy.rules.core.InferenceRulesEngine; import org.jeasy.rules.core.RuleBuilder; import org.jeasy.rules.core.RulesEngineParameters; import org.jeasy.rules.mvel.MVELRule; import org.jeasy.rules.support.UnitRuleGroup; import org.songdan.easy.rules.model.NumObj; /** * @author: coco_xu * @create: 2020-04-16 **/ public class FizzBuzzMainWIthFluent { public static void main(String[] args) { Rule fizzRule = new RuleBuilder().name("fizzRule").description("fizz num").when(new Condition() { public boolean evaluate(Facts facts) { Integer num = facts.get("num"); return num % 5 == 0; } }).then(new Action() { public void execute(Facts facts) throws Exception { System.out.println(facts.get("num")+" is a fizz num!!!"); } }).priority(1).build(); Rule buzzRule = new RuleBuilder().name("fizzRule").description("fizz num").when(new Condition() { public boolean evaluate(Facts facts) { Integer num = facts.get("num"); return num % 7 == 0; } }).then(new Action() { public void execute(Facts facts) throws Exception { System.out.println(facts.get("num")+" is a buzz num!!!"); } }).priority(2).build(); UnitRuleGroup unitRuleGroup = new UnitRuleGroup("mixRule","fizz and buzz num ",3); unitRuleGroup.addRule(fizzRule); unitRuleGroup.addRule(buzzRule); MVELRule mvelRule = new MVELRule() .name("weather rule") .description("if it rains then take an umbrella") .when("obj.generate() == 10") .then("System.out.println(\"It rains, take an umbrella!\");"); RulesEngineParameters parameters = new RulesEngineParameters().skipOnFirstAppliedRule(false); RulesEngine fizzBuzzEngine = new DefaultRulesEngine(parameters); Facts facts = new Facts(); Rules rules = new Rules(); rules.register(fizzRule); rules.register(buzzRule); rules.register(unitRuleGroup); rules.register(mvelRule); for (int i = 0; i < 100; i++) { facts.put("num",i); fizzBuzzEngine.fire(rules,facts); System.out.println(); } facts.put("obj", new NumObj(10)); fizzBuzzEngine.fire(rules,facts); } }
3、在yml文件中配置规则,然后进行读取
package org.songdan.easy.rules.yml; import org.jeasy.rules.api.Facts; import org.jeasy.rules.api.Rules; import org.jeasy.rules.api.RulesEngine; import org.jeasy.rules.core.DefaultRulesEngine; import org.jeasy.rules.core.RulesEngineParameters; import org.jeasy.rules.mvel.MVELRuleFactory; import org.songdan.easy.rules.anno.DiseaseModel; import java.io.FileNotFoundException; import java.io.InputStreamReader; /** * @author: coco_xu * @create: 2020-04-16 **/ public class FizzBuzzMainWithYmlRule { private static String result ; public static void main(String[] args) throws FileNotFoundException { // create a rules engine RulesEngineParameters parameters = new RulesEngineParameters().skipOnFirstAppliedRule(true); RulesEngine fizzBuzzEngine = new DefaultRulesEngine(parameters); InputStreamReader inputStreamReader = new InputStreamReader(FizzBuzzMainWithYmlRule.class.getClassLoader().getResourceAsStream("rules_string.yml")); // create rules Rules rules = MVELRuleFactory.createRulesFrom(inputStreamReader); // fire rules Facts facts = new Facts(); DiseaseModel diseaseModel = new DiseaseModel("ssss化疗"); String input ="ssss化疗"; facts.put("diseaseModel", diseaseModel); fizzBuzzEngine.fire(rules, facts); System.out.println(diseaseModel.getResult()); } }
二、使用easy-rules返回数据对象
easy-rules的返回结果中只能使用void方法,不能直接返回Object。否则报错:
Exception in thread "main" java.lang.IllegalArgumentException: Action method 'public java.lang.String org.easy.rules.anno.RuleClass$FizzRule.printFizz()' defined in rule 'org.songdan.easy.rules.anno.RuleClass$FizzRule' must be public, must return void type and may have parameters annotated with @Fact (and/or exactly one parameter of type or extending Facts).
此时可以将输入定义为一个实体类,在action中,直接修改需要修改的内容即可,如下:
---
name: "rule_1_对症治疗"
description: "print fizz if the number is multiple of 5"
priority: 1
condition: "diseaseModel.getInput().contains(\"对症治疗\")"
actions:
- "diseaseModel.result = \"对症治疗\")"
---
name: "rule_2_子宫平滑肌瘤"
description: "print buzz if the number is multiple of 7"
priority: 2
condition: "diseaseModel.getInput().contains(\"子宫平滑肌瘤\")"
actions:
- "diseaseModel.result = \"子宫平滑肌瘤\")"
---
name: "rule_3_化学治疗"
description: "diseaseModel.getInput().contains(\"化疗\") "
priority: 3
condition: "diseaseModel.getInput().contains(\"化疗\") || input.contains(\"化学治疗\")"
actions:
- "diseaseModel.result = \"化学治疗\""