规则引擎之easyRules

规则引擎听起来是蛮高深的一个词语,但透过现象看本质,Martin Fowler 有如下言:

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的注解:

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的注解用来判断是否触发:

@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());
    }

}

还支持多个规则组成的实现:

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之后,就是如何使用了

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();

上面的代码只是一个示意,稍微改下就可以运行。

 

别忘了添加依赖:

<dependency>
<groupId>org.easyrules</groupId>
<artifactId>easyrules-core</artifactId>
<version>2.4.0</version>
</dependency>

版本现在好像已经到3.3了 而且改动蛮大 上面的代码在3.3里可能不能运行。
posted @ 2019-03-08 17:53  boiledwater  阅读(1212)  评论(0编辑  收藏  举报