Giter VIP home page Giter VIP logo

rule-pile's Introduction

rule-pile

基于 Groovy 的决策和规则引擎

原理

基于 Java 运行时调用 Groovy 脚本的能力,可以让 Java 具备像脚本一样的灵活性。
核心代码:Java 执行 Groovy 脚本传参并获取结果

/**
 * 生成新的groovyClass
 */
private Class buildGroovyClass(String groovyScript) throws RuleException {
    // 每个class都new一个loader 便于垃圾回收
    GroovyClassLoader loader = new GroovyClassLoader();
    try {
        return loader.parseClass(groovyScript);
    } catch (Exception e) {
        throw new RuleException("groovy脚本解析class出错:" + e.getMessage());
    }
}
···
// 获取groovyObject
GroovyObject go = (GroovyObject) clazz.newInstance();
// 传参并调用脚本的main方法 
Object result = groovyObject.invokeMethod("main", input);

实现

有了基本原理后,其实问题被转变成了如何生成Groovy脚本?,理所当然的回答是:开发写呗。
这样的做法是可行的,但有几个问题:

  1. 开发累死
  2. 容易出错
  3. 无法感受现有的逻辑

这里的解决方案是: 图编辑器->生成逻辑流程图->解析为Groovy脚本->执行。可见即可得

图编辑器

图编辑器选择g6,准确来说选择开箱即用的ant-design-pro+GGEditor,前端要改的内容其实不多,为应对生成逻辑的需要,需要添加一些表单项即可

解析图和逻辑依赖

编辑器的输出是node数组和edge数组,就是图上的节点和线们。后台解析这段json后,生成逻辑树。之后对逻辑树进行遍历后,生成最后的Groovy脚本。
逻辑树的遍历:

void recursiveTravelNodeMap(Node node) throws RuleParseException {
    switch (node.getCategory()) {
        case "start":
           ···
        case "end":
           ···
        case "logic":
           ···
        case "common":
           ···
        default:
    }
    // node的后续节点
    for (ConnectNode target : node.getTargets()) {
        ···
        if (BOOLEAN_TRUE.equalsIgnoreCase(stream) && BOOLEAN_TRUE.equalsIgnoreCase(valve)) {
            this.recursiveTravelNodeMap(target.getNode());
        } else {
            this.mainBuilder.append("if ((").append(stream).append(").equals(").append(valve).append(")) {");
            this.recursiveTravelNodeMap(target.getNode());
            this.mainBuilder.append("}\n");
        }
    }
    if (defaultTarget != null) {
        this.recursiveTravelNodeMap(defaultTarget.getNode());
    }
}

为了复用现有逻辑,提供了一套逻辑依赖的解析:

// 使用模版生成函数main方法 脚本入口
StringBuilder resultScript = new StringBuilder(String.format(template,
        mainRule.getRuleCode(), this.buildFuncOptions(mainRule.getOptions(), true)));
// 将依赖的规则函数体放入
for (RuRuleDefinition dependency : dependencies) {
    this.expandResultScript(resultScript, dependency);
}
return resultScript.toString();

具体设计

rule-pile's People

Contributors

jimuyang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

rule-pile's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.