python 规则引擎 drools_Drools 规则引擎环境搭建
一、關(guān)于 drools 規(guī)則引擎
前面寫過一篇 Drools 規(guī)則引擎相關(guān)的文章,這篇文章主要記錄一下規(guī)則引擎的環(huán)境搭建和簡單示例。不熟悉 drools 的朋友可以看看這篇文章: 自己寫個(gè) Drools 文件語法檢查工具——棧的應(yīng)用之編譯器檢測語法錯(cuò)誤
介紹的內(nèi)容:
Drools 規(guī)則引擎的使用場景
Drools 規(guī)則引擎的優(yōu)點(diǎn)
Drools的基本工作工程(Fact對(duì)象、Drl文件內(nèi)容、Drools的基礎(chǔ)語法)
drools 文件的形式
Drools 文件語法初步檢查
二 、Drools 的環(huán)境搭建及簡單示例
環(huán)境: idea + jdk1.8 + gradle
我用的是 gradle 構(gòu)建 java 工程的方式、用 maven 構(gòu)建的可以參考配置
構(gòu)造這樣一個(gè)需求背景,雙十一來了,商品打折,假設(shè)商品價(jià)格 (0,500], 打85折,商品價(jià)格 (500, 1000],打8折, 商品價(jià)格 (1000,∞), 一律減 300。
1. 創(chuàng)建項(xiàng)目
新建一個(gè) gradle 項(xiàng)目,創(chuàng)建包:com.sharpcj,新建類 Product.java 和 Main.java:
Product.java 文件如下:
package com.sharpcj;
public class Product {
private String name; // 商品名稱
private double prePrice; // 商品定價(jià)
private double realPrice; //商品實(shí)際售價(jià)
public Product() {
}
public Product(String name, double prePrice) {
this.name = name;
this.prePrice = prePrice;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrePrice() {
return prePrice;
}
public void setPrePrice(double prePrice) {
this.prePrice = prePrice;
}
public double getRealPrice() {
return realPrice;
}
public void setRealPrice(double realPrice) {
this.realPrice = realPrice;
}
}
然后在 Main.java 新建 main 方法。
2. Gradle引入Drools庫
打開 build.gradle 文件,添加相應(yīng)的插件和依賴
plugins {
id 'java'
}
plugins {
id 'application'
}
mainClassName = 'com.sharpcj.Main'
group 'com.sharpcj'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile group: 'org.kie', name: 'kie-api', version: '7.5.0.Final'
compile group: 'org.drools', name: 'drools-compiler', version: '7.5.0.Final'
}
引入 Java 插件,使Gradle可以構(gòu)建Java代碼,同時(shí)引入了執(zhí)行Drools依賴的兩個(gè)庫, 指定了 mainClassName。
3.編寫 drools 文件
在 resources 目錄下面新建包 demo.rules,用來存放 drools 規(guī)則文件。然后新建文件 product.drl,
內(nèi)容如下:
package com.sharpcj;
rule "Product price less than 500" // 給規(guī)則取個(gè)名
when
pp : Product( prePrice <= 500 ) // 規(guī)則
then
// 符合規(guī)則后執(zhí)行的操作,是Java代碼
double prePrice = pp.getPrePrice();
pp.setRealPrice(prePrice * 0.85);
System.out.println(pp.getName() + "活動(dòng)價(jià)是:" + pp.getRealPrice());
end
rule "Product price less than 1000" // 給規(guī)則取個(gè)名
when
p : Product( prePrice > 500 && prePrice <=1000 ) // 規(guī)則
then
// 符合規(guī)則后執(zhí)行的操作,是Java代碼
double prePrice = p.getPrePrice();
p.setRealPrice(prePrice * 0.8);
System.out.println(p.getName() + "活動(dòng)價(jià)是:" + p.getRealPrice());
end
rule "Product price more than 1000" // 給規(guī)則取個(gè)名
when
p : Product( prePrice > 1000 ) // 規(guī)則
then
// 符合規(guī)則后執(zhí)行的操作,是Java代碼
double prePrice = p.getPrePrice();
p.setRealPrice(prePrice - 300);
System.out.println(p.getName() + "活動(dòng)價(jià)是:" + p.getRealPrice());
end
4.編寫配置文件
運(yùn)行 drools 需要一個(gè)固定的配置文件,在 resources 文件下的目錄 META_INF,名稱固定為 kmodule.xml:
配置文件至少包含如下幾行:
配置簡單說明:
Kmodule中可以包含一個(gè)到多個(gè)kbase,分別對(duì)應(yīng)drl的規(guī)則文件。
Kbase需要一個(gè)唯一的name,可以取任意字符串。
packages為drl文件所在resource目錄下的路徑。注意區(qū)分drl文件中的package與此處的package不一定相同。
多個(gè)包用逗號(hào)分隔。默認(rèn)情況下會(huì)掃描resources目錄下所有(包含子目錄)規(guī)則文件。
kbase的default屬性,標(biāo)示當(dāng)前KieBase是不是默認(rèn)的,如果是默認(rèn)的則不用名稱就可以查找到該KieBase,但每個(gè)module最多只能有一個(gè)默認(rèn)KieBase。
kbase下面可以有一個(gè)或多個(gè)ksession,ksession的name屬性必須設(shè)置,且必須唯一。
5.讓規(guī)則文件程序跑起來
在 Main.java 類中編寫測試方法,讓規(guī)則文件跑起來:
package com.sharpcj;
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
public class Main {
public static void main(String[] args){
new Main().test();
}
private void test(){
// 構(gòu)建KieServices
KieServices ks = KieServices.Factory.get();
KieContainer kc = ks.getKieClasspathContainer();
// 獲取kmodule.xml中配置中名稱為ksession-rule的session,默認(rèn)為有狀態(tài)的。
KieSession kSession = kc.newKieSession("ksession1");
Product fan = new Product("電扇", 280);
Product washer = new Product("洗衣機(jī)",2200);
Product phone = new Product("手機(jī)", 998);
kSession.insert(fan);
kSession.insert(washer);
kSession.insert(phone);
kSession.fireAllRules();
kSession.dispose();
}
}
運(yùn)行結(jié)果:
三、其它說明
1.不使用配置文件形式
上面使用的配置文件形式加載 drools 文件是 drools 7.x 版本才有的,在此之前,我們通常使用代碼形式加載規(guī)則文件,當(dāng)然在 drools 7.x 中依然可以使用這種方式,只不過有些 API 已經(jīng)過時(shí)了,或者更新了。下面用代碼形式加載規(guī)則文件代碼如下:
/**
* 不使用 drools 7.x 配置文件
*/
private void test2(){
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("demo/rules/product.drl"), ResourceType.DRL);
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
for (KnowledgeBuilderError error: errors) {
System.err.println(error);
}
throw new IllegalArgumentException("Could not parse knowledge.");
}
// 注釋掉的是 drools 6.x API
/*KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();*/
// drools 7.x API
InternalKnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
Collection pkgs = kbuilder.getKnowledgePackages();
kbase.addPackages(pkgs);
KieSession kieSession = kbase.newKieSession();
Product fan = new Product("電扇", 280);
Product washer = new Product("洗衣機(jī)",2200);
Product phone = new Product("手機(jī)", 998);
kieSession.insert(fan);
kieSession.insert(washer);
kieSession.insert(phone);
kieSession.fireAllRules();
kieSession.dispose();
}
運(yùn)行程序依然能得到相同的結(jié)果。
2.規(guī)則文件的類型
規(guī)則文件除了 drl 文件之類,還有其它類型的文件,如 xls, csv。
四、附錄
總結(jié)
以上是生活随笔為你收集整理的python 规则引擎 drools_Drools 规则引擎环境搭建的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微软发布Visual Studio 20
- 下一篇: 球迷必备Euro Cup Mobile