你的位置:首页 > ASP.net教程

[ASP.net教程]基于NXBRE规则引擎实现的柔性折扣策略


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

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

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

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

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

  折扣逻辑配置使用柔性折扣策略的目的。

  折扣规则文件:discount.xbre 

 1 <??> 2 <xBusinessRules ="http://www.w3.org/2001/ xsi:noNamespaceSchemaLocation="xBusinessRules.xsd"> 3   <!-- 全局变量--> 4   <Integer id="10i" value="10"/> 5   <Integer id="40i" value="40"/>  6   <ObjectLookup id="QuantityOrdered" objectId="CurrentOrder" member="Quantity"/> 7   <Logic> 8     <If> 9       <And>10         <GreaterThanEqualTo leftId="ClientRating" rightId="ClientRatingThreshold">11            <!-- CurrentOrder为订单对象-->12           <ObjectLookup id="ClientRating" objectId="CurrentOrder" member="ClientRating"/>13           <String id="ClientRatingThreshold" value="C"/>14         </GreaterThanEqualTo>15       </And>16       <Do>17         <!-- 对于评分高的客户指定的折扣策略 Discount rules for high rate customers -->18         <Logic>19           <If>20             <And>21               <GreaterThan leftId="QuantityOrdered" rightId="40i"/>22             </And>23             <Do>24              <!-- AppliedDiscount为应用的折扣-->25               <Evaluate id="AppliedDiscount">26                <!-- Percent为折扣比例-->27                 <Parameter name="Percent" value=".7"/>28               </Evaluate>29             </Do>30           </If>31           <ElseIf>32             <And>33               <GreaterThan leftId="QuantityOrdered" rightId="10i"/>34             </And>35             <Do>36               <Evaluate id="AppliedDiscount">37                 <Parameter name="Percent" value=".8"/>38               </Evaluate>39             </Do>40           </ElseIf>41           <Else>42             <Evaluate id="AppliedDiscount">43               <Parameter name="Percent" value=".9"/>44             </Evaluate>45           </Else>46         </Logic>47       </Do>48     </If>49     <Else>50       <!-- 对于评分低的客户指定的折扣策略 Discount rules for low rate customers -->51       <Logic>52         <If>53           <And>54             <GreaterThan leftId="QuantityOrdered" rightId="40i"/>55           </And>56           <Do>57             <Evaluate id="AppliedDiscount">58               <Parameter name="Percent" value=".9"/>59             </Evaluate>60           </Do>61         </If>62         <Else>63           <Evaluate id="AppliedDiscount">64             <Parameter name="Percent" value="1"/>65           </Evaluate>66         </Else>67       </Logic>68     </Else>69   </Logic>70 </xBusinessRules>

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

 1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Threading.Tasks; 9 using System.Windows.Forms; 10 using System.Collections; 11 using NxBRE.FlowEngine; 12 using NxBRE.FlowEngine.IO; 13 using BREFactory = NxBRE.FlowEngine.Factories.BREFactory; 14 using Reflection = NxBRE.Util.Reflection; 15 namespace WinApp 16 { 17   public partial class frmDiscountRBE : Form 18   { 19     public frmDiscountRBE() 20     { 21       InitializeComponent(); 22  23     } 24     25     /// <summary> 26     /// 规则 27     /// </summary> 28     public const string FLOW_RULES_FILENAME = "discount.xbre"; 29     public const string ORDER = "CurrentOrder"; 30     public const string APPLIED_DISCOUNT = "AppliedDiscount"; 31     public const string PERCENT = "Percent"; 32     /**/ 33     /// <summary> 34     /// 定单 35     /// </summary> 36     struct Order 37     { 38       public Int32 Quantity; 39       public Double TotalCost; 40       public string ClientRating; 41       public Order(int _q, double _t, string _c) 42       { 43         this.Quantity = _q; 44         this.TotalCost = _t; 45         this.ClientRating = _c; 46       } 47     } 48     /**/ 49     /// <summary> 50     /// 计算结果 51     /// </summary> 52     /// <param name="aBRC">规则引挚上下文</param> 53     /// <param name="aMap"></param> 54     /// <param name="aStep"></param> 55     /// <returns>结果</returns> 56     static object AppliedDiscount(IBRERuleContext aBRC, IDictionary aMap, object aStep) 57     { 58       Order _order = (Order)aBRC.GetObject(ORDER); 59       double _d = Convert.ToDouble(Reflection.CastValue(aMap[PERCENT], typeof(double))); 60       return _order.TotalCost * _d; 61     } 62     private void btnDiscount_Click(object sender, EventArgs e) 63     { 64       try 65       { 66         //载入规则 67         IRulesDriver rulesDriver = new XBusinessRulesFileDriver(FLOW_RULES_FILENAME); 68         //工厂 69         BREFactory breFactory = new BREFactory(); 70         //引挚实例 71         IFlowEngine bre = breFactory.NewBRE(rulesDriver); 72         //委托实例 73         ExecuteRuleDelegate executeRuleDelegate = new ExecuteRuleDelegate(AppliedDiscount); 74         bre.RuleContext.SetFactory(APPLIED_DISCOUNT, new BRERuleFactory(executeRuleDelegate)); 75         //设置规则引挚环境变量 76         //Order order = new Order(5, 25, "A"); 77         Order order = new Order(Int32.Parse(this.txtQuantity.Text), Double.Parse(this.txtTotalCost.Text), this.txtClientRating.Text); 78         bre.RuleContext.SetObject(ORDER, order); 79         //执行 80         bre.Process(); 81         //得到执行结果 82         double result = (double)bre.RuleContext.GetResult(APPLIED_DISCOUNT).Result; 83  84         this.txtPayCost.Text = result.ToString(); 85         this.txtPayCost.ReadOnly = true; 86         //Console.Out.WriteLine("\nOrder: Calculated discounted total={0} (expected: {1})\n", 87         //             result, 25); 88         //Console.ReadLine(); 89       } 90       catch (Exception ex) 91       { 92         MessageBox.Show(ex.Message); 93       } 94     } 95  96     private void frmDiscountRBE_Load(object sender, EventArgs e) 97     { 98  99     }100    101   }102 }

  运行程序,界面如下:

数量>40,折扣0.7数量大于10且小于40,折扣0.8