2015-06-01 37 views
1

NRules SimpleRule的代碼定義下列規則:如何做到最佳寫入規則定義NRules

public class PreferredCustomerDiscountRule : Rule 
{ 
    public override void Define() 
    { 
     Customer customer = null; 
     IEnumerable<Order> orders = null; 

     When() 
      .Match<Customer>(() => customer, c => c.IsPreferred) 
      .Collect<Order>(() => orders, 
       o => o.Customer == customer, 
       o => o.IsOpen, 
       o => !o.IsDiscounted); 

     Then() 
      .Do(ctx => ApplyDiscount(orders, 10.0)) 
      .Do(ctx => LogOrders(orders)) 
      .Do(ctx => orders.ToList().ForEach(ctx.Update)); 
    } 
     ... 
} 

我很奇怪,爲什麼條件是隻使用& &運營商即代替單獨pareameters將以下具有相同的效果?

public class PreferredCustomerDiscountRule : Rule 
{ 
    public override void Define() 
    { 
     Customer customer = null; 
     IEnumerable<Order> orders = null; 

     When() 
      .Match<Customer>(() => customer, c => c.IsPreferred) 
      .Collect<Order>(() => orders, 
       o => o.Customer == customer && o.IsOpen && !o.IsDiscounted); 

     Then() 
      .Do(ctx => ApplyDiscount(orders, 10.0)) 
      .Do(ctx => LogOrders(orders)) 
      .Do(ctx => orders.ToList().ForEach(ctx.Update)); 
    } 
     ... 
} 

回答

1

這兩個定義應該做同樣的事情。 Collect方法需要一個Expression<Func<T, bool>>的數組。第一個將它分成3個單獨的條件,而第二個只使用一個條件(和組合)。

我認爲這是一個口味問題,你喜歡哪一個。但與第一個很清楚哪些條件是相關的,你可以很容易地刪除或添加條件(通過評論/ /)。

7

提供單個條件表達式與由'& &'分隔的組件以及提供多個條件表達式之間存在差異。

在幕後,規則被編譯成網絡(rete網絡),並且每個條件由網絡中的節點表示。當多個規則共享相同的條件子集時,這些節點將在網絡中共享,從而提高效率(因爲評估條件較少)。由於節點共享,提供多個條件表達式給引擎更多的優化機會。

另一個區別是條件短路。當使用'& &'運算符提供單個條件表達式時,將應用標準C#條件短路。如果第一個條件是錯誤的,則不評估第二個條件。當提供多個條件時(這是因爲優化是由不同級別的引擎完成的),這不一定是正確的。

最佳做法是使用多個條件表達式而不是單個'& &'。