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 = \"化學治療\""

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM