規則引擎由推理引擎發展而來,是一種嵌入在應用程序中的組件,實現了將業務決策從應用程序代碼中分離出來,並使用預定義的語義模塊編寫業務決策。接受數據輸入,解釋業務規則,並根據業務規則做出業務決策。應用背景: 企業級管理者對企業IT系統的開發有著如下的要求:
1. 為提高效率,管理流程必須自動化,即使現代商業規則異常復雜。
2. 市場要求業務規則經常變化,IT系統必須依據業務規則的變化快速、低成本的更新。
3. 為了快速、低成本的更新,業務人員應能直接管理IT系統中的規則,不需要程序開發人員參與。
下面介紹一個開源的引擎(NXBRE Rule-engine)實現動態折扣價格計算:
折扣邏輯配置使用XML(擴展名.xbre)為文件,後期修改XML打折策略,在程序代碼無需修改的情況,實現柔性折扣策略的目的。
折扣規則文件:discount.xbre
1 <?xml version="1.0" encoding="UTF-8"?> 2 <xBusinessRules xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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 /// 規則xml文件名稱 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