基于NXBRE规则引擎实现的柔性折扣策略

  规则引擎由推理引擎发展而来,是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接受数据输入,解释业务规则,并根据业务规则做出业务决策。应用背景: 企业级管理者对企业IT系统的开发有着如下的要求:

1. 为提高效率,管理流程必须自动化,即使现代商业规则异常复杂。

2. 市场要求业务规则经常变化,IT系统必须依据业务规则的变化快速、低成本的更新。

3. 为了快速、低成本的更新,业务人员应能直接管理IT系统中的规则,不需要程序开发人员参与。

  下面介绍一个开源的引擎(NXBRE  Rule-engine)实现动态折扣价格计算:

  折扣逻辑配置使用XML(扩展名.xbre)为文件,后期修改XML打折策略,在程序代码无需修改的情况,实现柔性折扣策略的目的。

  折扣规则文件:discount.xbre 

 <?xml version="1.0" encoding="UTF-8"?>
<xBusinessRules xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xBusinessRules.xsd">
<!-- 全局变量-->
<Integer id="10i" value="10"/>
<Integer id="40i" value="40"/>
<ObjectLookup id="QuantityOrdered" objectId="CurrentOrder" member="Quantity"/>
<Logic>
<If>
<And>
<GreaterThanEqualTo leftId="ClientRating" rightId="ClientRatingThreshold">
<!-- CurrentOrder为订单对象-->
<ObjectLookup id="ClientRating" objectId="CurrentOrder" member="ClientRating"/>
<String id="ClientRatingThreshold" value="C"/>
</GreaterThanEqualTo>
</And>
<Do>
<!-- 对于评分高的客户指定的折扣策略 Discount rules for high rate customers -->
<Logic>
<If>
<And>
<GreaterThan leftId="QuantityOrdered" rightId="40i"/>
</And>
<Do>
<!-- AppliedDiscount为应用的折扣-->
<Evaluate id="AppliedDiscount">
<!-- Percent为折扣比例-->
<Parameter name="Percent" value=".7"/>
</Evaluate>
</Do>
</If>
<ElseIf>
<And>
<GreaterThan leftId="QuantityOrdered" rightId="10i"/>
</And>
<Do>
<Evaluate id="AppliedDiscount">
<Parameter name="Percent" value=".8"/>
</Evaluate>
</Do>
</ElseIf>
<Else>
<Evaluate id="AppliedDiscount">
<Parameter name="Percent" value=".9"/>
</Evaluate>
</Else>
</Logic>
</Do>
</If>
<Else>
<!-- 对于评分低的客户指定的折扣策略 Discount rules for low rate customers -->
<Logic>
<If>
<And>
<GreaterThan leftId="QuantityOrdered" rightId="40i"/>
</And>
<Do>
<Evaluate id="AppliedDiscount">
<Parameter name="Percent" value=".9"/>
</Evaluate>
</Do>
</If>
<Else>
<Evaluate id="AppliedDiscount">
<Parameter name="Percent" value="1"/>
</Evaluate>
</Else>
</Logic>
</Else>
</Logic>
</xBusinessRules>

  所有的业务逻辑都在discount.xbre 中定义,下面我们定义一个窗体来解析折扣逻辑并显示计算的结果:

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections;
using NxBRE.FlowEngine;
using NxBRE.FlowEngine.IO;
using BREFactory = NxBRE.FlowEngine.Factories.BREFactory;
using Reflection = NxBRE.Util.Reflection;
namespace WinApp
{
public partial class frmDiscountRBE : Form
{
public frmDiscountRBE()
{
InitializeComponent(); } /// <summary>
/// 规则xml文件名称
/// </summary>
public const string FLOW_RULES_FILENAME = "discount.xbre";
public const string ORDER = "CurrentOrder";
public const string APPLIED_DISCOUNT = "AppliedDiscount";
public const string PERCENT = "Percent";
/**/
/// <summary>
/// 定单
/// </summary>
struct Order
{
public Int32 Quantity;
public Double TotalCost;
public string ClientRating;
public Order(int _q, double _t, string _c)
{
this.Quantity = _q;
this.TotalCost = _t;
this.ClientRating = _c;
}
}
/**/
/// <summary>
/// 计算结果
/// </summary>
/// <param name="aBRC">规则引挚上下文</param>
/// <param name="aMap"></param>
/// <param name="aStep"></param>
/// <returns>结果</returns>
static object AppliedDiscount(IBRERuleContext aBRC, IDictionary aMap, object aStep)
{
Order _order = (Order)aBRC.GetObject(ORDER);
double _d = Convert.ToDouble(Reflection.CastValue(aMap[PERCENT], typeof(double)));
return _order.TotalCost * _d;
}
private void btnDiscount_Click(object sender, EventArgs e)
{
try
{
//载入规则
IRulesDriver rulesDriver = new XBusinessRulesFileDriver(FLOW_RULES_FILENAME);
//工厂
BREFactory breFactory = new BREFactory();
//引挚实例
IFlowEngine bre = breFactory.NewBRE(rulesDriver);
//委托实例
ExecuteRuleDelegate executeRuleDelegate = new ExecuteRuleDelegate(AppliedDiscount);
bre.RuleContext.SetFactory(APPLIED_DISCOUNT, new BRERuleFactory(executeRuleDelegate));
//设置规则引挚环境变量
//Order order = new Order(5, 25, "A");
Order order = new Order(Int32.Parse(this.txtQuantity.Text), Double.Parse(this.txtTotalCost.Text), this.txtClientRating.Text);
bre.RuleContext.SetObject(ORDER, order);
//执行
bre.Process();
//得到执行结果
double result = (double)bre.RuleContext.GetResult(APPLIED_DISCOUNT).Result; this.txtPayCost.Text = result.ToString();
this.txtPayCost.ReadOnly = true;
//Console.Out.WriteLine("\nOrder: Calculated discounted total={0} (expected: {1})\n",
// result, 25);
//Console.ReadLine();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
} private void frmDiscountRBE_Load(object sender, EventArgs e)
{ } }
}

  运行程序,界面如下:

基于NXBRE规则引擎实现的柔性折扣策略 基于NXBRE规则引擎实现的柔性折扣策略
数量>40,折扣0.7 数量大于10且小于40,折扣0.8
上一篇:规则引擎集成接口(七)规则引擎调用Java类


下一篇:VS 2005 修复重置(深度重置)