2009-07-27 20 views
4

我一直在嘗試爲我的系統中的一組規則實現流暢的界面。我試圖完成的是這在流暢的界面中實現條件

TicketRules 
.RequireValidation() 
.When(quartType => quartType == QuartType.Before).TotalMilageIs(64) 
.When(quartType => quartType == QuartType.After).TotalMilageIs(128); 

但是,我有麻煩實施條件時,我打算如何。目前,我需要)當(調用就像這個片斷兩次:

rules.When(param => param.Remarque == "Test").TotalMilageIs(100); 
rules.When(param => param.Remarque == "Other").TotalMilageIs(50); 

var params1 = new AddTicketParameters() { Remarque = "Test" }; 
var params2 = new AddTicketParameters() { Remarque = "Other" }; 

rules.ExecuteWith(params1); 

Assert.That(ticket.TotalMilage, Is.EqualTo(100)); 

rules.ExecuteWith(params2); 

Assert.That(ticket.TotalMilage, Is.EqualTo(50)); 

我TicketRules類如下這樣:

[EditorBrowsable(EditorBrowsableState.Never)] 
public class TicketRules : ITicketRule, IHideObjectMembers 
{ 
    private Ticket theTicket; 

    public Ticket Ticket 
    { 
     set 
     { 
      theTicket = value; 
     } 
    } 

    private List<ITicketRule> allRules = new List<ITicketRule>(); 

    public TicketRules() 
    { 
    } 

    public TicketRules(Ticket ticket) 
    { 
     theTicket = ticket; 
    } 

    public void Execute() 
    { 
     ExecuteWith(null, null); 
    } 

    public void ExecuteWith(AddTicketParameters param) 
    { 
     ExecuteWith(param, null); 
    } 

    public virtual void ExecuteWith(AddTicketParameters param, Ticket outsideTicket) 
    { 
     foreach (ITicketRule rule in allRules) 
     { 
      rule.ExecuteWith(param, theTicket ?? outsideTicket); 
     } 
    } 

    public TicketRules RequireValidation() 
    { 
     CreateModifierRule(ticket => ticket.NeedValidation = true); 
     return this; 
    } 

    public TicketRules TotalMilageIs(int milage) 
    { 
     CreateModifierRule(ticket => ticket.TotalMilage = milage); 
     return this; 
    } 

    private void CreateModifierRule(Action<Ticket> function) 
    { 
     AddRule(new ModifierTicketRule(function)); 
    } 

    internal void AddRule(ITicketRule rule) 
    { 
     allRules.Add(rule); 
    } 

    public WhenClauseTicketRule When(Predicate<AddTicketParameters> predicate) 
    { 
     WhenClauseTicketRule whenClause = new WhenClauseTicketRule(); 
     whenClause.Predicate = predicate; 

     AddRule(whenClause); 

     return whenClause; 
    } 

    public TicketRules UseStandardFormulaForTotalMilageAndTime() 
    { 
     AddRule(new StandardFormulaTicketRule()); 
     return this; 
    } 

    public TicketRules EnsureMinimumMilageIs(int milage) 
    { 
     AddRule(new EnsureMinimumMilageTicketRule(milage)); 
     return this; 
    } 
} 

的ITicketRules

internal interface ITicketRule : IHideObjectMembers 
{ 
    void ExecuteWith(AddTicketParameters param, Ticket ticket); 
} 

我還需要支持When子句中的AddTicketParameters的子類(我可能會使用泛型)。我在這裏發帖是因爲我的設計都很困惑,Martin Fowler articles讓我更加迷惑。

+0

你有沒有得到這個實現全面工作?奇怪的是,這個話題並沒有那麼多。你能將你的工作解決方案發布到這個問題上,還是直接發給我?謝謝! – 2009-09-29 21:43:17

回答

3

這就是所謂的整理問題時method chaining 試試這個

TicketRules 
.RequireValidation() 
.When(quartType => quartType == QuartType.Before, 
     rule => rule.TotalMilageIs(64)) 
.When(quartType => quartType == QuartType.After, 
     rule => rule.TotalMilageIs(128)); 

起初看上去有點古怪,但它包裝你的條件語句爲不同的範圍,所以你可以有條件地執行它們。想想它就像創建自己的if塊一樣。通過關閉它,你知道什麼時候可以「完成」一個子語句。

+0

第二個參數是表達式樹對嗎?因爲它需要創建一個規則類的新實例。 問題是我不能使用表達式樹,因爲它是一個.NET 2.0項目。我使用C#3.0編譯器認爲 – 2009-07-27 19:32:45