国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

規(guī)則引擎入門-基于easy-rules

這篇具有很好參考價(jià)值的文章主要介紹了規(guī)則引擎入門-基于easy-rules。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

概念理解

描述一個(gè)簡單的處理:基于一堆現(xiàn)實(shí)情況,運(yùn)用規(guī)則引擎、經(jīng)過處理得到對(duì)應(yīng)的結(jié)果,然后再據(jù)此做后續(xù)的事情。

  • fact: 事實(shí),已有的現(xiàn)實(shí)情況,即輸入信息
  • rules: 規(guī)則集合,由一系列規(guī)則組成,可能有不同的規(guī)則排列
  • rule: 規(guī)則,包含基本的判斷條件和條件符合要做的動(dòng)作。
  • condition: 規(guī)則的判定條件(特定的判斷邏輯 if else)
  • action: 規(guī)則判定符合后執(zhí)行的動(dòng)作
    規(guī)則引擎入門-基于easy-rules

實(shí)例和編碼

一句話描述: 提著去酒店買酒,需要判斷是否成年人,成年人才能購買酒,商店據(jù)此賣你酒,你買到了酒就裝包里走人,回家喝酒去。

接下來看easy-rules的定義和處理。

抽象出2條規(guī)則

@Rule(name = "age-rule", description = "age-rule", priority = 1)
public class AgeRule {

    @Condition
    public boolean isAdult(@Fact("person") Person person) {
        return person.getAge() > 18;
    }

    @Action
    public void setAdult(@Fact("person") Person person) {
        person.setAdult(true);
    }
}
package org.jeasy.rules.tutorials.shop;

import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Fact;
import org.jeasy.rules.annotation.Rule;

/**
 * @author dingqi on 2023/5/26
 * @since 1.0.0
 */
@Rule(name = "alcohol-rule", description = "alcohol-rule", priority = 2)
public class AlcoholRule {

    @Condition
    public boolean shopRule(@Fact("person") Person person) {
        return person.isAdult() == true;
    }

    @Action
    public void shopReply(@Fact("bag") Bag bag) {
        bag.setSuccess(true);
        bag.add("Vodka");
    }
}

簡單的規(guī)則引擎

// create a rule set
Rules rules = new Rules();
rules.register(new AgeRule());
rules.register(new AlcoholRule());

//create a default rules engine and fire rules on known facts
DefaultRulesEngine rulesEngine = new DefaultRulesEngine();

事實(shí)1的處理

Facts facts = new Facts();
Person tom = new Person("Tom", 19);
facts.put("person", tom);
Bag bag = new Bag();
facts.put("bag", bag);

System.out.println("Tom: Hi! can I have some Vodka please?");
rulesEngine.fire(rules, facts);
System.out.println("Tom: bag is " + bag);

輸出:Tom成年了,買到了伏特加

Tom: Hi! can I have some Vodka please?
Tom: bag is Bag{success=true, goods=[Vodka]}

事實(shí)2的處理

Person jack = new Person("Jack", 10);
facts.put("person", jack);
Bag bag2 = new Bag();
facts.put("bag", bag2);

System.out.println("Jack: Hi! can I have some Vodka please?");
rulesEngine.fire(rules, facts);
System.out.println("Jack: bag is " + bag2);

輸出:Jack未成年,無功而返

Jack: Hi! can I have some Vodka please?
Jack: bag is Bag{success=false, goods=[]}

easy-rules 規(guī)則的抽象和執(zhí)行

事實(shí)描述

public class Facts implements Iterable<Fact<?>> {

    private final Set<Fact<?>> facts = new HashSet<>();

/**
 * A class representing a named fact. Facts have unique names within a {@link Facts}
 * instance.
 * 
 * @param <T> type of the fact
 * @author Mahmoud Ben Hassine
 */
public class Fact<T> {
	
	private final String name;
	private final T value;

事實(shí)簡單就是key、value對(duì), 某個(gè)事實(shí)的名稱,和事實(shí)的屬性特征(以一切皆對(duì)象來看,就是一個(gè)一個(gè)的對(duì)象組成了事實(shí))。(只要在規(guī)則條件真正執(zhí)行前,能明確這些事實(shí)就行)

規(guī)則的抽象

  • 名稱
  • 描述
  • 優(yōu)先級(jí)
  • 執(zhí)行Facts的的方法

org.jeasy.rules.api.Rule接口 和基礎(chǔ)實(shí)現(xiàn)類org.jeasy.rules.core.BasicRule

條件和動(dòng)作注解:

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Condition {

}
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Condition {

}
默認(rèn)的規(guī)則
class DefaultRule extends BasicRule {

    private final Condition condition;
    private final List<Action> actions;

    DefaultRule(String name, String description, int priority, Condition condition, List<Action> actions) {
        super(name, description, priority);
        this.condition = condition;
        this.actions = actions;
    }

    @Override
    public boolean evaluate(Facts facts) {
        return condition.evaluate(facts);
    }

    @Override
    public void execute(Facts facts) throws Exception {
        for (Action action : actions) {
            action.execute(facts);
        }
    }

}

動(dòng)態(tài)代理執(zhí)行規(guī)則和動(dòng)作

使用org.jeasy.rules.api.Rules添加規(guī)則時(shí)如下:

  • org.jeasy.rules.api.Rules#register
 public void register(Object... rules) {
     Objects.requireNonNull(rules);
     for (Object rule : rules) {
         Objects.requireNonNull(rule);
         this.rules.add(RuleProxy.asRule(rule));
     }
 }

使用org.jeasy.rules.annotation.Rule注解構(gòu)造的規(guī)則是使用RuleProxy構(gòu)造的
規(guī)則引擎入門-基于easy-rules

規(guī)則的執(zhí)行:org.jeasy.rules.core.DefaultRulesEngine#doFire
void doFire(Rules rules, Facts facts) {
    if (rules.isEmpty()) {
        LOGGER.warn("No rules registered! Nothing to apply");
        return;
    }
    logEngineParameters();
    log(rules);
    log(facts);
    LOGGER.debug("Rules evaluation started");
    for (Rule rule : rules) {
        final String name = rule.getName();
        final int priority = rule.getPriority();
        if (priority > parameters.getPriorityThreshold()) {
            LOGGER.debug("Rule priority threshold ({}) exceeded at rule '{}' with priority={}, next rules will be skipped",
                    parameters.getPriorityThreshold(), name, priority);
            break;
        }
        if (!shouldBeEvaluated(rule, facts)) {
            LOGGER.debug("Rule '{}' has been skipped before being evaluated", name);
            continue;
        }
        boolean evaluationResult = false;
        try {
            evaluationResult = rule.evaluate(facts);
        } catch (RuntimeException exception) {
            LOGGER.error("Rule '" + name + "' evaluated with error", exception);
            triggerListenersOnEvaluationError(rule, facts, exception);
            // give the option to either skip next rules on evaluation error or continue by considering the evaluation error as false
            if (parameters.isSkipOnFirstNonTriggeredRule()) {
                LOGGER.debug("Next rules will be skipped since parameter skipOnFirstNonTriggeredRule is set");
                break;
            }
        }
        if (evaluationResult) {
            LOGGER.debug("Rule '{}' triggered", name);
            triggerListenersAfterEvaluate(rule, facts, true);
            try {
                triggerListenersBeforeExecute(rule, facts);
                rule.execute(facts);
                LOGGER.debug("Rule '{}' performed successfully", name);
                triggerListenersOnSuccess(rule, facts);
                if (parameters.isSkipOnFirstAppliedRule()) {
                    LOGGER.debug("Next rules will be skipped since parameter skipOnFirstAppliedRule is set");
                    break;
                }
            } catch (Exception exception) {
                LOGGER.error("Rule '" + name + "' performed with error", exception);
                triggerListenersOnFailure(rule, exception, facts);
                if (parameters.isSkipOnFirstFailedRule()) {
                    LOGGER.debug("Next rules will be skipped since parameter skipOnFirstFailedRule is set");
                    break;
                }
            }
        } else {
            LOGGER.debug("Rule '{}' has been evaluated to false, it has not been executed", name);
            triggerListenersAfterEvaluate(rule, facts, false);
            if (parameters.isSkipOnFirstNonTriggeredRule()) {
                LOGGER.debug("Next rules will be skipped since parameter skipOnFirstNonTriggeredRule is set");
                break;
            }
        }
    }
}

默認(rèn)的規(guī)則引擎直接遍歷規(guī)則去執(zhí)行,如果condition執(zhí)行命中后,則去執(zhí)行action

public class RuleProxy implements InvocationHandler

規(guī)則引擎入門-基于easy-rules

private Object evaluateMethod(final Object[] args) throws IllegalAccessException, InvocationTargetException {
    Facts facts = (Facts) args[0];
    Method conditionMethod = getConditionMethod();
    try {
        List<Object> actualParameters = getActualParameters(conditionMethod, facts);
        return conditionMethod.invoke(target, actualParameters.toArray()); // validated upfront
    } catch (NoSuchFactException e) {
        LOGGER.warn("Rule '{}' has been evaluated to false due to a declared but missing fact '{}' in {}",
                getTargetClass().getName(), e.getMissingFact(), facts);
        return false;
    } catch (IllegalArgumentException e) {
        LOGGER.warn("Types of injected facts in method '{}' in rule '{}' do not match parameters types",
                conditionMethod.getName(), getTargetClass().getName(), e);
        return false;
    }
}
規(guī)則執(zhí)行監(jiān)聽器

在規(guī)則執(zhí)行的過程中,可以做各種操作??梢钥闯梢?guī)則的擴(kuò)展點(diǎn)

/**
 * A listener for rule execution events.
 *
 * @author Mahmoud Ben Hassine (mahmoud.benhassine@icloud.com)
 */
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) { }

}

回顧規(guī)則執(zhí)行和監(jiān)聽器的執(zhí)行過程

// 1. 條件執(zhí)行前
triggerListenersBeforeEvaluate(rule, facts);
try {
	evaluationResult = rule.evaluate(facts);
} catch(Exception e){
	 // 2. 條件執(zhí)行失敗
	 triggerListenersOnEvaluationError(rule, facts, exception);
}

if (evaluationResult) {
	// 3. 條件執(zhí)行后(條件滿足)
	triggerListenersAfterEvaluate(rule, facts, true);
	 try {
	 	  // 4. 動(dòng)作執(zhí)行前
	 	  triggerListenersBeforeExecute(rule, facts);
          rule.execute(facts);
          // 5. 動(dòng)作執(zhí)行后
          triggerListenersOnSuccess(rule, facts);
	 } catch (Exception exception) {
	 	 // 6. 條件執(zhí)行失敗
	 	 triggerListenersOnFailure(rule, exception, facts);
	 }
}else{
	// 3. 條件執(zhí)行后(條件不滿足)
	triggerListenersAfterEvaluate(rule, facts, false);
}

擴(kuò)展

  1. Java Expression Language (JEXL) :表達(dá)式語言引擎

https://commons.apache.org/proper/commons-jexl/apidocs/org/apache/commons/jexl3/JexlEngine.html

  1. MVEL:一個(gè)功能強(qiáng)大的基于Java應(yīng)用程序的表達(dá)式語言。

  2. SpEL:Spring表達(dá)式語言文章來源地址http://www.zghlxwxcb.cn/news/detail-466216.html

name: adult rule
description: when age is greater than 18, then mark as adult
priority: 1
condition: "#{ ['person'].age > 18 }"
actions:
  - "#{ ['person'].setAdult(true) }"

到了這里,關(guān)于規(guī)則引擎入門-基于easy-rules的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Easy Rules規(guī)則引擎(2-細(xì)節(jié)篇)

    Easy Rules規(guī)則引擎(2-細(xì)節(jié)篇)

    在 Easy Rules規(guī)則引擎(1-基礎(chǔ)篇) 中我們已經(jīng)簡單介紹了 Easy Rules 規(guī)則引擎的使用示例,這節(jié)我們?cè)斀饨榻B一下規(guī)則引擎的相關(guān)參數(shù)配置實(shí)例還有組合規(guī)則。 Easy Rules 規(guī)則引擎支持下面參數(shù)配置: 參數(shù)名稱 參數(shù)類型 必選 默認(rèn)值 rulePriorityThreshold int 否 Integer.MAX_VALUE skipOnFirst

    2024年02月11日
    瀏覽(25)
  • python輕量規(guī)則引擎rule-engine入門與應(yīng)用實(shí)踐

    python輕量規(guī)則引擎rule-engine入門與應(yīng)用實(shí)踐

    rule-engine是一種輕量級(jí)、可選類型的表達(dá)式語言,具有用于匹配任意 Python 對(duì)象的自定義語法,使用python語言開發(fā)。 規(guī)則引擎表達(dá)式用自己的語言編寫,在 Python 中定義為字符串。其語法與 Python 最相似,但也受到 Ruby 的一些啟發(fā)。這種語言的一些特性包括: 可選類型提示 用

    2024年02月04日
    瀏覽(25)
  • 低代碼開發(fā)重要工具:jvs-rules 規(guī)則引擎功能介紹(三)

    低代碼開發(fā)重要工具:jvs-rules 規(guī)則引擎功能介紹(三)

    規(guī)則引擎是由多個(gè)組件組成的,這些組件共同協(xié)作實(shí)現(xiàn)規(guī)則的管理、執(zhí)行和決策流的構(gòu)建。 決策流:決策流是由多個(gè)業(yè)務(wù)節(jié)點(diǎn)連接而成的流程,用于實(shí)現(xiàn)復(fù)雜的業(yè)務(wù)邏輯。決策流中的業(yè)務(wù)節(jié)點(diǎn)按照特定的順序執(zhí)行,每個(gè)節(jié)點(diǎn)根據(jù)輸入數(shù)據(jù)和規(guī)則引擎的執(zhí)行結(jié)果,決定下一個(gè)要

    2024年02月15日
    瀏覽(26)
  • Java源碼規(guī)則引擎:jvs-rules 8月新增功能介紹

    Java源碼規(guī)則引擎:jvs-rules 8月新增功能介紹

    JVS-rules是JAVA語言下開發(fā)的規(guī)則引擎,是jvs企業(yè)級(jí)數(shù)字化解決方案中的重要配置化工具,核心解決業(yè)務(wù)判斷的配置化,常見的使用場(chǎng)景:金融信貸風(fēng)控判斷、商品優(yōu)惠折扣計(jì)算、對(duì)員工考核評(píng)分等各種變化的規(guī)則判斷情景。 8月是收獲的季節(jié),jvs-rules在這個(gè)季節(jié)到來之時(shí)做了大

    2024年02月14日
    瀏覽(22)
  • jvs-rules(規(guī)則引擎)1.23功能更新說明,新增SQL變量、數(shù)據(jù)源等

    jvs-rules(規(guī)則引擎)1.23功能更新說明,新增SQL變量、數(shù)據(jù)源等

    1、新增SQL變量: SQL變量通常指的是在執(zhí)行SQL查詢時(shí)使用的動(dòng)態(tài)變量。這些變量允許在查詢中注入或更改某些值,以便根據(jù)不同的條件或輸入執(zhí)行不同的查詢。 1.1 新增自定義SQL語言進(jìn)行數(shù)據(jù)查詢; 用戶可以使用自定義的SQL語句來查詢數(shù)據(jù)。通過這種方式,用戶可以在規(guī)則中

    2024年01月25日
    瀏覽(24)
  • 《基于 Vue 組件庫 的 Webpack5 配置》2.模塊規(guī)則 module.rule

    配置 module.rules ,創(chuàng)建模塊時(shí),匹配請(qǐng)求的規(guī)則數(shù)組; 可參考 webpack5 指南-管理資源; vue 可參考上述配置; js 使用 webpack babel-loader; css 參考 webpack 加載 CSS。注意 style-loader 和 vue-style-loader 選一個(gè)即可,兩者的功能基本一致,只是 vue-style-loader 可用于服務(wù)端渲染 SSR; stylus

    2024年02月11日
    瀏覽(32)
  • 【規(guī)則引擎】Drools急速入門

    【規(guī)則引擎】Drools急速入門

    1.Drools規(guī)則引擎簡介 (1)什么是規(guī)則引擎 ? 全稱為業(yè)務(wù)規(guī)則管理系統(tǒng),英?名為BRMS(即 Business Rule Management System)。規(guī)則引擎的主要思想是將應(yīng)用程序中的業(yè)務(wù)決策部分分離出來,并使用預(yù)定義的語義模塊編寫業(yè)務(wù)決策(業(yè)務(wù)規(guī)則),由用戶或開發(fā)者在需要時(shí)進(jìn)行配置、管理

    2024年02月05日
    瀏覽(19)
  • LiteFlow規(guī)則引擎的入門

    LiteFlow規(guī)則引擎的入門

    1、LiteFlow簡介 LiteFlow是一個(gè)非常強(qiáng)大的現(xiàn)代化的規(guī)則引擎框架,融合了編排特性和規(guī)則引擎的所有特性。 利用LiteFlow,你可以將瀑布流式的代碼,轉(zhuǎn)變成以組件為核心概念的代碼結(jié)構(gòu),這種結(jié)構(gòu)的好處是可以任意編排,組件與組件之間是解耦的,組件可以用腳本來定義,組件

    2024年02月05日
    瀏覽(15)
  • Java規(guī)則引擎Drools急速入門

    Java規(guī)則引擎Drools急速入門

    1.Drools規(guī)則引擎簡介 (1)什么是規(guī)則引擎 ? 全稱為業(yè)務(wù)規(guī)則管理系統(tǒng),英?名為BRMS(即 Business Rule Management System)。規(guī)則引擎的主要思想是將應(yīng)用程序中的業(yè)務(wù)決策部分分離出來,并使用預(yù)定義的語義模塊編寫業(yè)務(wù)決策(業(yè)務(wù)規(guī)則),由用戶或開發(fā)者在需要時(shí)進(jìn)行配置、管理

    2024年02月04日
    瀏覽(28)
  • 【游戲引擎Easy2D】基于基礎(chǔ)類型展開的監(jiān)聽器學(xué)習(xí)詳解

    【游戲引擎Easy2D】基于基礎(chǔ)類型展開的監(jiān)聽器學(xué)習(xí)詳解

    ?? ???♂? iecne個(gè)人主頁: 點(diǎn)贊關(guān)注收藏評(píng)論支持哦~ ??每天 關(guān)注 iecne的作品,一起進(jìn)步 ??本文收錄 專欄 :【C++游戲引擎】 ??希望大家多多支持??一起進(jìn)步呀! 哈嘍大家好,我是 iecne ,本期為大家?guī)淼氖荂PP/C++【游戲引擎Easy2D】一篇打通引擎頂級(jí)類型,Listener。包

    2024年01月17日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包