溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

怎么理解java規(guī)則引擎

發(fā)布時(shí)間:2021-11-18 10:13:49 來(lái)源:億速云 閱讀:335 作者:iii 欄目:編程語(yǔ)言

本篇內(nèi)容主要講解“怎么理解java規(guī)則引擎”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“怎么理解java規(guī)則引擎”吧!

WHAT

規(guī)則引擎由推理引擎發(fā)展而來(lái),是一種嵌入在應(yīng)用程序中的組件,實(shí)現(xiàn)了將業(yè)務(wù)決策從應(yīng)用程序代碼中分離出來(lái),并使用預(yù)定義的語(yǔ)義模塊編寫(xiě)業(yè)務(wù)決策。接受數(shù)據(jù)輸入。解釋業(yè)務(wù)規(guī)則,并根據(jù)業(yè)務(wù)規(guī)則作出業(yè)務(wù)決策。在Java中,大多數(shù)的規(guī)則引擎都實(shí)現(xiàn)JSR94。將規(guī)則引擎想象成一個(gè)以數(shù)據(jù)和規(guī)則作為輸入的系統(tǒng)。他講這些規(guī)則定義為我們提供輸出

if x then y

怎么理解java規(guī)則引擎

WHY

我們的業(yè)務(wù)代碼里充斥了大量的if/else,當(dāng)然,我們可以用策略模式+模板模式將if/else抽到各個(gè)子類(lèi)中。但是也增加了類(lèi)的復(fù)雜度。

硬編碼

如果需要修改Java類(lèi)中的邏輯,在更改進(jìn)入生產(chǎn)環(huán)境前,將會(huì)精力一個(gè)冗長(zhǎng)的過(guò)程

  1. 硬編碼開(kāi)發(fā)

  2. 測(cè)試代碼

  3. 審核代碼

  4. 部署代碼

引入規(guī)則引擎

服務(wù)接口單純化,將復(fù)雜多變的業(yè)務(wù)邏輯交給比高級(jí)語(yǔ)言更加接近自然語(yǔ)言的規(guī)則,讓用戶(hù)在web端或cs端自己進(jìn)行配置發(fā)布,將技術(shù)和業(yè)務(wù)邏輯解耦。

常用框架

drools

谷歌出品的規(guī)則引擎框架,也是很多公司選型的第一選擇。基于Charles Forgy's的RETE算法,易于調(diào)整以及易于管理的開(kāi)源業(yè)務(wù)規(guī)則引擎,符合業(yè)內(nèi)標(biāo)準(zhǔn)、速度快、效率高。業(yè)務(wù)分析人員或?qū)徍巳藛T可以利用給他輕松查看業(yè)務(wù)規(guī)則,檢驗(yàn)已編碼的規(guī)則執(zhí)行了所需業(yè)務(wù)規(guī)則。一般企業(yè)都會(huì)做二次開(kāi)發(fā),并且有web端可視化操作界面。

demo

無(wú)spring版本,maven引入drools

<dependency>
	<groupId>org.kie</groupId>
	<artifactId>kie-api</artifactId>
	<version>6.3.0.Final</version>
</dependency>
<dependency>
	<groupId>org.drools</groupId>
	<artifactId>drools-core</artifactId>
	<version>6.3.0.Final</version>
</dependency>
<dependency>
	<groupId>org.drools</groupId>
	<artifactId>drools-compiler</artifactId>
	<version>6.3.0.Final</version>
</dependency>
<dependency>
	<groupId>org.drools</groupId>
	<artifactId>drools-decisiontables</artifactId>
	<version>6.3.0.Final</version>
</dependency>
<dependency>
	<groupId>org.drools</groupId>
	<artifactId>drools-templates</artifactId>
	<version>6.3.0.Final</version>
</dependency>

需要在resources下增加META-INF文件夾,并且創(chuàng)建kmodule.xml聲明規(guī)則文件的關(guān)系

<?xml version="1.0" encoding="UTF-8" ?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmoudule">
	<kbase name="rules" packages="rules1">
		<ksession name="ksession-rules" />
	</kbase>
</kmodule>

編寫(xiě)規(guī)則文件,在resources下創(chuàng)建rules1文件夾,保證和xml文件中的packages一致。新建rule.drl文件,語(yǔ)法有點(diǎn)類(lèi)似java,最后還是要轉(zhuǎn)成java的

pacage com.ruleengine.drools
// 導(dǎo)入自定義實(shí)體類(lèi)
import com.ruleengine.drools.Message

// 規(guī)則名
rule 'VIP'
	when
	    // 進(jìn)入條件為 status是VIP,并且把message屬性給到printMsg,否則外部無(wú)法使用
		m : Message( status == Message.VIP , printMsg : message ) 
	then
		System.out.println( printMsg );
		m.setMessage( "普通用戶(hù)不打折" );
		m.setStatus( Message.COMMON_USER );
		// 更新實(shí)體
		update( m );
end

// 第二個(gè)規(guī)則
rule "commonUser"
	when
		Message( status == Message.COMMON_USER, printMsg : message )
	then
		System.out.println( printMsg );
end

調(diào)用

public class DroolsMain{
	public static void main(String[] args){
		KieServices kieServices = KieServices.Factory.get();
		KieContainer kieContainer = kieServices.getKieClasspathContainer();
		KieSession kSession = kieContainer.newKieSession("ksession-rules");
		Message m = new Message();
		m.setMessage("VIP打折");
		m.setStatus(Message.VIP);
		// 將實(shí)體類(lèi)插入執(zhí)行規(guī)則
		kSession.insert(m);
		kSession.fireAllRules();
	}
}

自定義類(lèi)

public class Message{
	public static final int VIP - 1;
	public staitc final int COMMON_USER = 0;
	private String message;
	private String status;
	public String getMessage(){return this.message;}
	public int getStatus(){ return this.status; }
	public void setMessage(String message){ this.message = message; }
	public void setStatus(int status){ this.status = status; }
}

特色代表-有贊

有贊最終選擇了drools規(guī)則引擎來(lái)做風(fēng)控邏輯。用來(lái)防御以下風(fēng)險(xiǎn):

  • 盜卡。例:盜用用戶(hù)銀行卡,在有贊店鋪上消費(fèi)

  • 欺詐。例:通過(guò)發(fā)布低價(jià)商品,誘騙消費(fèi)者購(gòu)買(mǎi)

  • 套現(xiàn)。例:在自己創(chuàng)建的店鋪里進(jìn)行虛假交易用以套現(xiàn)信用卡

  • 垃圾信息。例:發(fā)布虛假消息、色情等違規(guī)商品、頁(yè)面

  • 盜賬戶(hù)。例:黑客用其他平臺(tái)獲取的賬戶(hù)密碼通過(guò)撞庫(kù)來(lái)非法盜取用戶(hù)在贊平臺(tái)的賬戶(hù)

怎么理解java規(guī)則引擎

from https://tech.youzan.com/rules-engine/

easyrule

https://github.com/j-easy/easy-rules

特點(diǎn)

  • 輕量級(jí)框架和易于學(xué)習(xí)的API

  • 基于POJO的開(kāi)發(fā)和注解的編程模型

  • 支持從簡(jiǎn)單規(guī)則創(chuàng)建組合規(guī)則的能力

  • 支持使用表達(dá)式語(yǔ)言(如MVEL和SpEL),最新版本支持JEXL

概念

  • facts 規(guī)則引擎輸入

  • rule 規(guī)則 rules 規(guī)則集合

  • condition 匹配條件

  • action 執(zhí)行動(dòng)作

怎么理解java規(guī)則引擎

兩種方式定義規(guī)則

  • 通過(guò)在POJO上添加注釋?zhuān)月暶鞯姆绞蕉x

  • 通過(guò)RuleBuilder API,以編程方式定義

更多案例可以到這看 https://github.com/j-easy/easy-rules/tree/master/easy-rules-tutorials

maven引入,最新版本
<dependency>
	<groupId>org.jeasy</groupId>
	<artifactId>easy-rules-core</artifactId>
	<version>4.1.0</version>
</dependency>
POJO
package com.lrq.wechatdemo.rules;
 
import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Fact;
import org.jeasy.rules.annotation.Rule;
import org.jeasy.rules.support.UnitRuleGroup;

public class RuleClass {
 
    @Rule(priority = 1) //規(guī)則設(shè)定優(yōu)先級(jí)
    public static class FizzRule {
        @Condition // 返回值為boolean
        public boolean isFizz(@Fact("number") Integer number) {
            return number % 5 == 0;
        }
 
        @Action
        public void printFizz() {
            System.out.print("fizz\n");
        }
    }
 
    @Rule(priority = 2)
    public static class BuzzRule {
        @Condition
        public boolean isBuzz(@Fact("number") Integer number) {
            return number % 7 == 0;
        }
 
        @Action
        public void printBuzz() {
            System.out.print("buzz\n");
        }
    }
 
    public static class FizzBuzzRule extends UnitRuleGroup {
 
        public FizzBuzzRule(Object... rules) {
            for (Object rule : rules) {
                addRule(rule);
            }
        }
 
        @Override
        public int getPriority() {
            return 0;
        }
    }
 
    @Rule(priority = 3)
    public static class NonFizzBuzzRule {
 
        @Condition
        public boolean isNotFizzNorBuzz(@Fact("number") Integer number) {
            // can return true, because this is the latest rule to trigger according to
            // assigned priorities
            // and in which case, the number is not fizz nor buzz
            return number % 5 != 0 || number % 7 != 0;
        }
 
        @Action
        public void printInput(@Fact("number") Integer number) {
            System.out.print(number+"\n");
        }
    }
 
}

調(diào)用

import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.api.RulesEngine;
import org.jeasy.rules.core.DefaultRulesEngine;
import org.jeasy.rules.core.RulesEngineParameters;
 
public class RuleJavaClient {
    public static void main(String[] args) {
        // 創(chuàng)建規(guī)則引擎
        RulesEngineParameters parameters = new RulesEngineParameters().skipOnFirstAppliedRule(true);
        RulesEngine fizzBuzzEngine = new DefaultRulesEngine(parameters);
 
        // 創(chuàng)建規(guī)則集并注冊(cè)規(guī)則
        Rules rules = new Rules();
        rules.register(new RuleClass.FizzRule());
        rules.register(new RuleClass.BuzzRule());
        rules.register(new RuleClass.FizzBuzzRule(new RuleClass.FizzRule(), new RuleClass.BuzzRule()));
        rules.register(new RuleClass.NonFizzBuzzRule());
 
        // 執(zhí)行規(guī)則
        Facts facts = new Facts();
        for (int i = 1; i <= 100; i++) {
            facts.put("number", i);
            fizzBuzzEngine.fire(rules, facts);
            System.out.println();
        }
    }
 
}
yml

在resources下新建yml文件

---
name: "fizz rule"
description: "print fizz if the number is multiple of 5"
priority: 1
condition: "number % 5 == 0"
actions:
- "System.out.println(\"fizz\")"
 
---
name: "buzz rule"
description: "print buzz if the number is multiple of 7"
priority: 2
condition: "number % 7 == 0"
actions:
- "System.out.println(\"buzz\")"
 
---
name: "fizzbuzz rule"
description: "print fizzbuzz if the number is multiple of 5 and 7"
priority: 0
condition: "number % 5 == 0 && number % 7 == 0"
actions:
- "System.out.println(\"fizzbuzz\")"
 
---
name: "non fizzbuzz rule"
description: "print the number itself otherwise"
priority: 3
condition: "number % 5 != 0 || number % 7 != 0"
actions:
- "System.out.println(number)"

調(diào)用,將yml解析為rules

public class RuleYmlClient {
 
    public static void main(String[] args) throws FileNotFoundException {
        // create a rules engine
        RulesEngineParameters parameters = new RulesEngineParameters().skipOnFirstAppliedRule(true);
        RulesEngine fizzBuzzEngine = new DefaultRulesEngine(parameters);
 
        // load rules from yml
		MVELRuleFactory fuleFactory = new MVELRuleFactory(new YamlRuleDefinitionReader())
        Rules rules = fuleFactory.createRules(new FileReader("rule.yml"));
 
        // fire rules
        Facts facts = new Facts();
        for (int i = 1; i <= 100; i++) {
            facts.put("number", i);
            fizzBuzzEngine.fire(rules, facts);
            System.out.println();
        }
    }
}

URule

國(guó)內(nèi)的規(guī)則引擎,和drool一樣基于RETE算法建立的。URule Pro是一款由上海銳道信息技術(shù)有限公司自主研發(fā)的一款純Java規(guī)則引擎,它可以運(yùn)行在Windows、Linux、Unix等各種類(lèi)型的操作系統(tǒng)之上; URule Pro的規(guī)則設(shè)計(jì)器采用業(yè)內(nèi)首創(chuàng)的純?yōu)g覽器編輯模式,無(wú)須安裝任何工具,打開(kāi)瀏覽器即可完成復(fù)雜規(guī)則的設(shè)計(jì)與測(cè)試。 怎么理解java規(guī)則引擎


旗正規(guī)則引擎

旗正規(guī)則引擎是由國(guó)家科技部和財(cái)政部的創(chuàng)新基金支持,專(zhuān)門(mén)針對(duì)國(guó)內(nèi)規(guī)則引擎市場(chǎng)空白的情況,結(jié)合國(guó)內(nèi)項(xiàng)目的特點(diǎn)而開(kāi)發(fā)的一款業(yè)務(wù)規(guī)則管理系統(tǒng)(BRMS)產(chǎn)品。規(guī)則引擎以規(guī)則配置編輯器為規(guī)則錄入窗口,以規(guī)則引擎為系統(tǒng)運(yùn)轉(zhuǎn)動(dòng)力,以企業(yè)規(guī)則庫(kù)為業(yè)務(wù)邏輯基礎(chǔ),輔以規(guī)則協(xié)同管理、遠(yuǎn)程項(xiàng)目與服務(wù)管理、集群規(guī)則同步等功能模塊,實(shí)現(xiàn)業(yè)務(wù)邏輯的可視化定制,同時(shí)又具有快速開(kāi)發(fā)java軟件項(xiàng)目的功能

國(guó)內(nèi)比較大的商業(yè)級(jí)規(guī)則引擎,有專(zhuān)用的CS客戶(hù)端。并且支持規(guī)則測(cè)試、調(diào)用外部規(guī)則包、操作數(shù)據(jù)庫(kù)、解析excel等騷操作。

怎么理解java規(guī)則引擎

到此,相信大家對(duì)“怎么理解java規(guī)則引擎”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢(xún),關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI