【底层服务/编程功底系列】「手把手教学系列」带你打造一个属于自己的规则引擎服务,打破任何业务难题(逻辑模型和API设计)(一)https://developer.aliyun.com/article/1471068
Rule逻辑模型
规则是可以被规则引擎触发的抽象概念。规则需要在规则类型的命名空间中进行注册,并且每个规则必须具有唯一的名称。这样的设计使得规则引擎能够准确地识别和触发特定的规则。通过将规则注册到适当的命名空间中,并提供唯一的名称,我们能够确保规则的正确性和可靠性。这种规则抽象和命名约定的使用,使规则引擎的操作变得更加灵活和可维护。
Rule逻辑模型属性
Rule的逻辑模型的属性主要由规则名称、规则描述和规则的优先级三部分进行组成介绍。他们分别定义了规则的命名值,主要用于区分每个rule之间的唯一性以及对应的规则含义、多个规则之间的优先级。当然每一个属性都有自己的优先级。
Rule代码案例
java
复制代码
public interface Rule extends Comparable<Rule> { /** * Default rule name. */ String DEFAULT_NAME = "rule"; /** * Default rule description. */ String DEFAULT_DESCRIPTION = "description"; /** * Default rule priority. */ int DEFAULT_PRIORITY = Integer.MAX_VALUE - 1; /** * Getter for rule name. * @return the rule name */ default String getName() { return DEFAULT_NAME; } /** * Getter for rule description. * @return rule description */ default String getDescription() { return DEFAULT_DESCRIPTION; } /** * Getter for rule priority. * @return rule priority */ default int getPriority() { return DEFAULT_PRIORITY; } /** * This method implements the rule's condition(s). * <strong>Implementations should handle any runtime exception and return true/false accordingly</strong> * * @return true if the rule should be applied given the provided facts, false otherwise */ boolean evaluate(Facts facts); /** * This method implements the rule's action(s). * @throws Exception thrown if an exception occurs when performing action(s) */ void execute(Facts facts) throws Exception; }
Rule的规则行为
方法boolean evaluate(Facts facts);
主要用于代理与对应的Condition接口进行交互,从而处理和控制条件判断的走向。然而,需要注意的是,Rule类本身是一个门面操作,实际调用的方法属于Condition接口的具体实现类。类似地,void execute(Facts facts) throws Exception;
方法对应的是Action接口的方法。
这种设计模式允许Rule类作为一个中间层,将调用委托给具体的Condition和Action实现类,从而实现了更好的解耦。通过这种抽象和代理模式的应用,我们能够更加灵活地处理和控制条件判断和操作的逻辑。
Rules的工厂类操作
与Fact类似,Rule也有一个相似的Rules工厂类。这个工厂类是一个类型工厂集合,用于存储Rule对象的模型集合数据。它可以容纳多个规则信息,因为在条件流转的过程中,通常会存在多个规则模型,而不仅仅是一个。
通过使用这个Rules工厂类,我们可以方便地管理和操作Rule对象。它允许我们动态地添加、修改和删除规则,从而实现更灵活的条件流转控制。
代码案例
java
复制代码
public class Rules implements Iterable<Rule> { private Set<Rule> rules = new TreeSet<>(); /** * Create a new {@link Rules} object. * * @param rules to register */ public Rules(Set<Rule> rules) { this.rules = new TreeSet<>(rules); } /** * Create a new {@link Rules} object. * * @param rules to register */ public Rules(Rule... rules) { Collections.addAll(this.rules, rules); } /** * Create a new {@link Rules} object. * * @param rules to register */ public Rules(Object... rules) { this.register(rules); } /** * Register one or more new rules. * * @param rules to register, must not be null */ public void register(Object... rules) { Objects.requireNonNull(rules); for (Object rule : rules) { Objects.requireNonNull(rule); this.rules.add(RuleProxy.asRule(rule)); } } /** * Unregister one or more rules. * * @param rules to unregister, must not be null */ public void unregister(Object... rules) { Objects.requireNonNull(rules); for (Object rule : rules) { Objects.requireNonNull(rule); this.rules.remove(RuleProxy.asRule(rule)); } } /** * Unregister a rule by name. * * @param ruleName name of the rule to unregister, must not be null */ public void unregister(final String ruleName) { Objects.requireNonNull(ruleName); Rule rule = findRuleByName(ruleName); if (rule != null) { unregister(rule); } } /** * Check if the rule set is empty. * * @return true if the rule set is empty, false otherwise */ public boolean isEmpty() { return rules.isEmpty(); } /** * Clear rules. */ public void clear() { rules.clear(); } /** * Return how many rules are currently registered. * * @return the number of rules currently registered */ public int size() { return rules.size(); } /** * Return an iterator on the rules set. It is not intended to remove rules * using this iterator. * @return an iterator on the rules set */ @Override public Iterator<Rule> iterator() { return rules.iterator(); } private Rule findRuleByName(String ruleName) { return rules.stream() .filter(rule -> rule.getName().equalsIgnoreCase(ruleName)) .findFirst() .orElse(null); } }
运作流程模式
首先,在执行一个Rule规则模型时,它会经过Condition接口的执行。在这个步骤中,该规则会执行evaluate方法来判断条件是否满足。如果条件判断结果为true,接下来将执行Action操作,从而控制规则的处理模式。在整个过程中,Fact实际参数模型起着关键作用,它主要用于传输数据信息到各个执行路径节点。
RuleListener
RuleListener是规则执行事件的监听器,主要用于监控每个执行单元节点的执行前后Hook的AOP拦截作用,它也是主要面向于Action接口的实现方法以及Condition的实现方法,方便我们实时以及动态的审计方面进行控制我们的规则引擎的处理模式和实现方式。
Condition的审计操作
- beforeEvaluate:在评估规则前触发。
- afterEvaluate:在评估规则后触发。
- onEvaluationError:运行时异常导致条件评估错误时触发。
Action的审计操作
代码案例
java
复制代码
public interface RuleListener { /** * Triggered before the evaluation of a rule. * * @param rule being evaluated * @param facts known before evaluating the rule * @return true if the rule should be evaluated, false otherwise */ default boolean beforeEvaluate(Rule rule, Facts facts) { return true; } /** * Triggered after the evaluation of a rule. * * @param rule that has been evaluated * @param facts known after evaluating the rule * @param evaluationResult true if the rule evaluated to true, false otherwise */ default void afterEvaluate(Rule rule, Facts facts, boolean evaluationResult) { } /** * Triggered on condition evaluation error due to any runtime exception. * * @param rule that has been evaluated * @param facts known while evaluating the rule * @param exception that happened while attempting to evaluate the condition. */ default void onEvaluationError(Rule rule, Facts facts, Exception exception) { } /** * Triggered before the execution of a rule. * * @param rule the current rule * @param facts known facts before executing the rule */ default void beforeExecute(Rule rule, Facts facts) { } /** * Triggered after a rule has been executed successfully. * * @param rule the current rule * @param facts known facts after executing the rule */ default void onSuccess(Rule rule, Facts facts) { } /** * Triggered after a rule has failed. * * @param rule the current rule * @param facts known facts after executing the rule * @param exception the exception thrown when attempting to execute the rule */ default void onFailure(Rule rule, Facts facts, Exception exception) { } }
【底层服务/编程功底系列】「手把手教学系列」带你打造一个属于自己的规则引擎服务,打破任何业务难题(逻辑模型和API设计)(三)https://developer.aliyun.com/article/1471070