我一直在尝试为系统中的一组规则实现流畅的界面。我想要完成的是这个
TicketRules
.RequireValidation()
.When(quartType => quartType == QuartType.Before).TotalMilageIs(64)
.When(quartType => quartType == QuartType.After).TotalMilageIs(128);
但是,我无法实现有条件的方式。目前,我需要在此片段中调用When()两次:
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的子类(我虽然可能在该部分使用泛型)。我在这里张贴是因为我的设计让我很困惑,而马丁福勒articles让我更加困惑。
答案 0 :(得分:3)
这被称为method chaining时的整理问题 试试这个
TicketRules
.RequireValidation()
.When(quartType => quartType == QuartType.Before,
rule => rule.TotalMilageIs(64))
.When(quartType => quartType == QuartType.After,
rule => rule.TotalMilageIs(128));
一开始看起来有点奇怪,但它将你的条件包装到一个不同的范围内,所以你可以有条件地执行它们。想想它就像创建自己的if块一样。通过关闭它,您知道何时可以“完成”子语句。