您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center   Code  
会员   
   
 
     
   
 订阅
  捐助
JAVA规则引擎[Drools]--实例篇
 
  4168  次浏览      19
 2018-3-27 
 
编辑推荐:
本文来自于阿里云,本文通过一个例子把项目的开发规则部分独立提取出来,体现了Drools的价值就得到。

随着互联网应用的飞速发展,各种业务需求也应运而生,对于不断变更和革新的业务规则而言,项目的开发就很有必要把规则部分独立提取出来,此时Drools的价值就得到了体现。废话不多说,看一个简单的例子。

这里举一个手机话费的例子。

一、定义规则:

首先要分析自己的业务逻辑,根据业务而制定出不同的规则,这里我们假设有3个规则。

1、对于新开户的手机用户送20元话费。

2、在2014年10月到12期间充值的用户,不论金额多少充值满3次就赠送5元话费。

3、当月充值金额达到100以上,每达到一次赠送话费10元。

二、创建Fact对象:

分析这些规则,并把他们抽象成一个Fact对象。

package com.core.drools;

import java.util.UUID;

/**
* EntityRule-Model
* @author Candy
*
*/
public class EntityRule {

private String username;

/** Whether for new account. */
private boolean account;

/** The number of add. */
private int addtime;

/** The sum of the current account. */
private double currentmoney;

/** The totail amount added. */
private double totailaddmoney;

/**
* Record the serial number of the operation.
* @param username
* @param currentmoney
*/
public void getSerialnumber(String username,double currentmoney){
System.out.println("Account:"+username+" Balance:¥"+currentmoney);
System.out.println("Serial Number:"+UUID.randomUUID().toString());
}

三、定义规则引擎:

业务和规则都整理清楚了我们就可以开始规则引擎的核心部分啦,这里我定义的是接口和实现类。

package com.core.drools;

/**
* RuleEngine-Interface
* @author Candy
*
*/
public interface RuleEngine {

/**
* Initializes the rules engine.
*/
public void init();

/**
* Refresh the rules engine.
*/
public void refresh();

/**
* Execute the rules engine.
*/
public void execute(final EntityRule entityRule);

}

package com.core.drools;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import org.drools.RuleBase;
import org.drools.StatefulSession;
import org.drools.compiler.DroolsParserException;
import org.drools.compiler.PackageBuilder;
import org.drools.rule.Package;
import org.drools.spi.Activation;

/**
* RuleEngine-Implements
* @author Candy
*
*/
public class RuleEngineImpl implements

RuleEngine{

private RuleBase ruleBase;

/*
* (non-Javadoc)
* @see com.core.drools.RuleEngine#init()
*/
@Override
public void init() {
/** Sets the system time format. */
System.setProperty("drools.dateformat",

"yyyy-MM-dd HH:mm:ss");
/** Get the base factory. */
ruleBase =SingleRuleFactory.getRuleBase();
try {
/** Get the rule files has bean read. */
PackageBuilder backageBuilder = getPack

ageBuilderFile();
/** Add the package to the 'RuleBase'. */
ruleBase.addPackages(backageBuilder.

getPackages());
} catch (DroolsParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}

/*
* (non-Javadoc)
* @see com.core.drools.RuleEngine#refresh()
*/
@Override
public void refresh() {
ruleBase = SingleRuleFactory.getRuleBase();
Package[] packages = ruleBase.getPackages();
for(Package items :packages){
ruleBase.removePackage(items.getName());
}
init();
}

/*
* (non-Javadoc)
* @see com.core.drools.RuleEngine#execute

(com.core.drools.EntityRule)
*/
@Override
public void execute(final EntityRule entityRule) {
if(null == ruleBase.getPackages() || 0 == ruleBase.getPackages().length) {
return;
}

StatefulSession statefulSession =

ruleBase.newStatefulSession();
statefulSession.insert(entityRule);
statefulSession.fireAllRules(new org.

drools.spi.AgendaFilter() {
public boolean accept(Activation activation) {
return !activation.getRule().getName().

contains("_test");
}
});
statefulSession.dispose();
}

/**
* Read the rule files.
* @return
* @throws Exception
*/
private PackageBuilder getPackageBuild

erFile()throws Exception {
/** Get the rule files. */
List<String> drlFilePath = getRuleFile();
/** Sets the file to 'readers'. */
List<Reader> readers = loadRuleFile(drlFilePath);
/** To create the 'backageBuilder'. */
PackageBuilder backageBuilder = new PackageBuilder();
for (Reader r : readers) {
backageBuilder.addPackageFromDrl(r);
}
/** Check if the script has a problem. */
if(backageBuilder.hasErrors()) {
throw new Exception(backageBuilder.

getErrors().toString());
}
return backageBuilder;
}

/**
* Load the script files.
* @param drlFilePath
* @return
* @throws FileNotFoundException
*/
private List<Reader> loadRuleFile(List

<String> drlFilePath)
throws FileNotFoundException {
if (null == drlFilePath || 0 == drlFilePath.size()) {
return null;
}
List<Reader> readers = new ArrayList<Reader>();
for (String ruleFilePath : drlFilePath) {
readers.add(new FileReader(new File(ruleFilePath)));
}
return readers;
}

/**
* Get the rule files.
* @return
*/
private List<String> getRuleFile(){
List<String> drlFilePath = new ArrayList<String>();
String path="D:/utils/my/DroolsProject/src/

com/core/drools/drools_rule.drl";
drlFilePath.add(path);
return drlFilePath;
}

}

这里定义一个单例的RuleBase工厂类。

package com.core.drools;

import org.drools.RuleBase;
import org.drools.RuleBaseFactory;

/**
* To create a singleton factory.
* @author Candy
*
*/
public class SingleRuleFactory {

private static RuleBase ruleBase;

/**
* Get the base factory.
* @return
*/
public static RuleBase getRuleBase(){
return null != ruleBase ? ruleBase : RuleBaseFactory.newRuleBase();
}

}

四、编写规则文件:

规则文件可以根据自己的业务需求定义多个文件,这里我只定义了一个。

package com.core.drools

import com.core.drools.EntityRule;

rule accountEntity
//One
salience 100
lock-on-active true
when
$entityRule : EntityRule(account == true)
then
System.out.println("The new account:Present

¥20.0");
$entityRule.setCurrentmoney($entityRule.

getCurrentmoney()+20);
$entityRule.getSerialnumber($entityRule.

getUsername(),$entityRule.getCurrentmoney());
System.out.println
end

rule billEntity
//two
salience 99
lock-on-active true
date-effective "2014-010-01 00:00:00"
date-expires "2014-012-31 23:59:59"
when
$entityRule : EntityRule(addtime >= 3)
then
System.out.println("Prepaid phone number

reach "+$entityRule.getAddtime()
+" times:Present ¥"+$entityRule.getAddtime()/3*5);
$entityRule.setCurrentmoney($entityRule.

getCurrentmoney()+$entityRule.getAddtime()/3*5);
$entityRule.getSerialnumber($entityRule.

getUsername(),$entityRule.getCurrentmoney());
System.out.println
end

rule addMoney
//Three
salience 98
lock-on-active true
when
$entityRule : EntityRule(totailaddmoney >= 100)
then
System.out.println("The account for

the month top-up totail amount is "
+$entityRule.getTotailaddmoney()+":Present ¥"+(int)$entityRule.getTotailaddmoney()/100*10);
$entityRule.setCurrentmoney($entityRule.getCurrentmoney()
+(int)$entityRule.getTotailaddmoney()/100 * 10);
$entityRule.getSerialnumber($entityRule.

getUsername(),$entityRule.getCurrentmoney());
end

五、测试引擎:

package com.test;

import java.io.IOException;
import com.core.drools.EntityRule;
import com.core.drools.RuleEngine;
import com.core.drools.RuleEngineImpl;

/**
* Test Drools
* @author Candy
*
*/
public class DroolsTest {

public static void main(String[] args) throws IOException {
RuleEngine engineImpl =new RuleEngineImpl();
engineImpl.init();
final EntityRule entityRule= new EntityRule();
entityRule.setCurrentmoney(350d);
entityRule.setUsername("Candy");
entityRule.setAccount(true);
entityRule.setTotailaddmoney(350d);
entityRule.setAddtime(7);
engineImpl.execute(entityRule);
}

}

六、测试结果:

The new account:Present ¥20.0

Account:Candy Balance:¥370.0

Serial Number:0fd98593-caa2-444d-a4ff-b4001cfb3260

------------------------------------------------------------------------------

Prepaid phone number reach 7 times:Present ¥10

Account:Candy Balance:¥380.0

Serial Number:a118b211-c28e-4035-aa60-2f417f62b2f3

------------------------------------------------------------------------------

The account for the month top-up totail amount is 350.0: Present ¥30

Account:Candy Balance:¥410.0

Serial Number:2bfc02c2-267f-47a2-9cda-5a4196e2b7cf

   
4168 次浏览       19
相关文章

Java微服务新生代之Nacos
深入理解Java中的容器
Java容器详解
Java代码质量检查工具及使用案例
相关文档

Java性能优化
Spring框架
SSM框架简单简绍
从零开始学java编程经典
相关课程

高性能Java编程与系统性能优化
JavaEE架构、 设计模式及性能调优
Java编程基础到应用开发
JAVA虚拟机原理剖析