規則引擎之easyRules

規則引擎聽起來是蠻高深的一個詞語,但透過現象看本質,Martin Fowler 有以下言:ide

You can build a simple rules engine yourself. All you need is to create a bunch of objects with conditions and actions, store them in a collection, and run through them to evaluate the conditions and execute the actions.
雖然一個完美的規則引擎不會這麼簡單,可是若是你只是想要一個夠用的規則引擎,這個定義就還蠻清楚的。
一樣就有人根據這個想法,已經實現了一個簡單的規則名字,easyRules,好吧,名字也是簡單。下面咱們就看看如何使用這個規則引擎。
首先仍是先定義了一個接口,這個不是必須的,只是爲了後續使用方便:
public interface IRule {
    void setInput(JobEntity jobEntity);
    String getDescription();
}

基類有一些基本的實現,注意action和priority的註解:ui

public abstract class BaseRule implements IRule{
    protected JobEntity value;
    private String desc;

    public BaseRule(String desc){
        this.desc = desc;
    }

    @Override
    public String getDescription() {
        return desc;
    }

    @Override
    public void setInput(JobEntity jobEntity){
        this.value = jobEntity;
    }

    @Action
    public void printWarning(){
        System.out.print(....);
    }

    @Priority
    public int getPriority(){
        return 1;
    }
}

真正的一個實現類,condition的註解用來判斷是否觸發:this

@Rule
public class BlackListUserRule extends BaseRule{
    private List<String> blackList = new ArrayList<>();

    public BlackListUserRule(RuleItemEntity ruleItemEntity){
        super(ruleItemEntity.getDesc()) ;

        if (ruleItemEntity.getBwType().equalsIgnoreCase(Constants.CHECK_BLACKLIST) &&
                ruleItemEntity.getCheckType().equalsIgnoreCase(Constants.CHECK_USER) &&
                null != ruleItemEntity.getCheckValue()) {
            String[] users = ruleItemEntity.getCheckValue().split(";");
            blackList.addAll(Arrays.asList(users));
        }
    }

    @Condition
    public boolean inBlackList(){
        if(blackList.size() == 0){
            return false;
        }

        return blackList.contains(value.getUser());
    }

}

還支持多個規則組成的實現:lua

public class MultipleRules extends CompositeRule implements IRule{

    public MultipleRules(Object... rules){
        for (Object rule : rules) {
            addRule(rule);
        }
    }

    @Override
    public void execute() throws Exception {
        super.execute();
        System.out.println("CompositeRule reached.");
    }

    @Override
    public void setInput(JobEntity jobEntity) {
        if (!rules.isEmpty()) {
            for (Rule rule : rules) {
                if (rule instanceof IRule) {
                    IRule iRule = (IRule) rule;
                    iRule.setInput(jobEntity);
                }
            }
        }
    }
}

在創建完rule以後,就是如何使用了spa

RulesEngine jobRulesEngine= RulesEngineBuilder.aNewRulesEngine().withSkipOnFirstAppliedRule(false)
                .withSilentMode(true).build();

 for (RuleEntity ruleEntityEnt : ruleEntityEntList) {
            IRule rule = RuleFactory.getRule(ruleEntityEnt);
            if (null != rule) {
                jobRulesEngine.registerRule(rule);
                ruleList.add(rule);
            }
        }

 for (IRule rule : ruleList) {
            rule.setInput(jobEntity);
        }

        jobRulesEngine.fireRules();

上面的代碼只是一個示意,稍微改下就能夠運行。code

 

別忘了添加依賴:blog

<dependency>    <groupId>org.easyrules</groupId>    <artifactId>easyrules-core</artifactId>    <version>2.4.0</version></dependency>版本如今好像已經到3.3了 並且改動蠻大 上面的代碼在3.3裏可能不能運行。
相關文章
相關標籤/搜索