【思路】使用Java手写入参是 Json对象,根据json对象中type值不同,选择不同规则链的自定义规则节点的支持过滤、支持分支的规则引擎案例

  • 作者: 凯哥Java(公众号:凯哥Java)
  • 工作小总结
  • 时间:2023-04-20 11:35
  • 2548人已阅读
简介 正在为您搜索:Java、手写、Json对象、type值这是一个相对复杂的案例,但是我会尽力解释。首先,我们需要考虑如何定义规则节点。在这个案例中,规则节点应该包含以下属性:节点名称条件:一些表达式,用于表示当这些条件为真时,规则应该被触发。动作:当规则被触发时应该执行的操作,可以是输出日志、发送邮件等。然后,我们需要定义规则链,它由多个规则节点连接而成。规则链应该有一个入口(也就是第一个规则节点)

🔔🔔🔔好消息!好消息!🔔🔔🔔

有需要的朋友👉:联系凯哥 微信号 kaigejava2022

正在为您搜索:Java、手写、Json对象、type值


这是一个相对复杂的案例,但是我会尽力解释。首先,我们需要考虑如何定义规则节点。在这个案例中,规则节点应该包含以下属性:


节点名称

条件:一些表达式,用于表示当这些条件为真时,规则应该被触发。

动作:当规则被触发时应该执行的操作,可以是输出日志、发送邮件等。

然后,我们需要定义规则链,它由多个规则节点连接而成。规则链应该有一个入口(也就是第一个规则节点),并且每个规则节点应该有他们的后继节点。


这里需要注意的是,规则节点和规则链应该是可以动态配置的。例如,某些规则节点可能不再适用于当前场景,需要从规则链中删除。另外,新的规则节点也应该可以被添加到规则链中。


在这个案例中,我们还需要根据输入的 JSON 对象来选择适当的规则链。例如,如果 JSON 对象中的 type 值为 "A",则应该选择规则链 A,否则选择规则链 B。


下面是一个简单的 Java 代码实现,实现了上述的要求:


java

public class Rule {
    private String name; // 规则名称
    private List<Expression> conditions; // 条件列表
    private Action action; // 规则动作

    public Rule(String name, List<Expression> conditions, Action action) {
        this.name = name;
        this.conditions = conditions;
        this.action = action;
    }

    // 以下是 getter 和 setter 方法
    // ...
}

public class RuleChain {
    private List<RuleNode> ruleNodes; // 规则节点列表
    private Map<String, RuleNode> ruleNodeMap; // 规则节点名称 -> 规则节点

    public RuleChain() {
        this.ruleNodes = new ArrayList<>();
        this.ruleNodeMap = new HashMap<>();
    }

    public void addNode(RuleNode ruleNode) {
        this.ruleNodes.add(ruleNode);
        this.ruleNodeMap.put(ruleNode.getName(), ruleNode);
    }

    public RuleNode getEntryNode() {
        return this.ruleNodes.get(0);
    }

    public RuleNode getNodeByName(String name) {
        return this.ruleNodeMap.get(name);
    }

    // getter 和 setter 方法
    // ...
}

public class RuleNode {
    private String name; // 规则节点名称
    private List<Expression> conditions; // 条件列表
    private List<String> nextNodeNames; // 后继节点名称列表
    private Action action; // 规则动作

    public RuleNode(String name, List<Expression> conditions, List<String> nextNodeNames, Action action) {
        this.name = name;
        this.conditions = conditions;
        this.nextNodeNames = nextNodeNames;
        this.action = action;
    }

    // 以下是 getter 和 setter 方法
    // ...
}

public class FilterRuleEngine {
    private Map<String, RuleChain> ruleChains;

    public FilterRuleEngine() {
        this.ruleChains = new HashMap<>();
    }

    public void addRuleChain(String type, RuleChain ruleChain) {
        this.ruleChains.put(type, ruleChain);
    }

    public List<Action> evaluate(JSONObject obj) {
        String type = obj.getString("type");
        RuleChain ruleChain = this.ruleChains.get(type);
        if (ruleChain == null) {
            return Collections.emptyList();
        }

        Facts facts = new Facts(obj);
        RuleNode currentNode = ruleChain.getEntryNode();
        List<Action> actions = new ArrayList<>();
        while (currentNode != null) {
            if (ruleApplies(currentNode, facts)) {
                if (currentNode.getAction() != null) {
                    actions.add(currentNode.getAction());
                }
                String nextNodeName = getNodeToExecute(currentNode, facts);
                if (nextNodeName == null) {
                    break;
                }
                currentNode = ruleChain.getNodeByName(nextNodeName);
            } else {
                currentNode = null;
            }
        }
        return actions;
    }

    private boolean ruleApplies(RuleNode node, Facts facts) {
        boolean result = true;
        for (Expression condition : node.getConditions()) {
            result = result && condition.evaluate(facts);
        }
        return result;
    }

    private String getNodeToExecute(RuleNode node, Facts facts) {
        for (String nextNodeName : node.getNextNodeNames()) {
            RuleNode nextNode = node.getParent().getNodeByName(nextNodeName);
            if (ruleApplies(nextNode, facts)) {
                return nextNode.getName();
            }
        }
        return null;
    }
}

public class Facts {
    private JSONObject obj;

    public Facts(JSONObject obj) {
        this.obj = obj;
    }

    public Object get(String name) {
        return this.obj.get(name);
    }
}

这里我们使用 JSONObject 类,来表示输入的 JSON 对象。Facts 类则封装了 JSONObject 对象,使得我们可以像之前一样使用 get() 方法来获取属性值。行为类的定义与之前一样,没有变化。


在 FilterRuleEngine 类中,我们新增了一个 ruleChains 字段,用于存放不同类型规则链的映射关系。在 addRuleChain() 方法中,我们可以将不同类型规则链添加到这个映射关系中。在 evaluate() 方法中,我们根据输入的 JSON 对象中的 type 值来选择适当的规则链,如果没有找到则返回一个空列表。


接下来,在evaluate()方法中,我们创建了一个Facts对象,用于向规则节点提供条件所需要的数据。然后,我们获取规则链的入口节点,并且循环遍历规则链中的所有节点,依次评估它们的条件并执行相应的操作。当我们遇到没有匹配的后继节点时,我们退出循环并返回所有收集到的操作(如果有)。


最后,我们还需要为规则节点和规则链提供 getter 和 setter 方法,以便其他代码可以自由地配置它们。


TopTop