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 = \"化学治疗\""

 

posted @ 2020-04-16 18:02  Co~Co  阅读(5023)  评论(0编辑  收藏  举报