是否可以编写一个遵循给定语法的TestDataBuilder?
例如:
我知道如何为一辆不是问题的汽车写一个基本的建造者。
但我怎样才能实现,我只能在门上添加新窗户?
所以这是允许的:
var car = CarBuilderWithSyntax.Create()
.WithDoor()
.HavingSide(Sides.Left)
.WithWindow()
.HavingWidth(50)
.HavingHeight(50)
.Build();
但这是不允许:
var car = CarBuilderWithSyntax.Create()
.WithWindow()
.HavingWidth(50)
.HavingHeight(50)
.Build();
是否有可能强制执行此语法规则?
这可以通过使用继承汽车制造商的额外门构造器来实现吗?
汽车制造商应该实施不同的界面,例如IDoorBuilderWithSyntax,它定义方法ICarBuilderWithSyntax WithWindow()
和ICarBuilderWithSyntax HavingSide();
ICarBuilderWithSyntax HavingColor()
?
答案 0 :(得分:2)
您可以执行以下操作:
public enum Sides
{
Left,
}
public class Car
{
}
public class CarBuilderWithSyntax
{
protected CarBuilderWithSyntax ParentBuilder { get; private set; }
public static CarBuilderWithSyntax Create()
{
return new CarBuilderWithSyntax(null);
}
protected CarBuilderWithSyntax(CarBuilderWithSyntax parent)
{
ParentBuilder = parent;
}
protected CarBuilderWithSyntax GetParentBuilder()
{
CarBuilderWithSyntax parentBuilder = this;
while (parentBuilder.ParentBuilder != null)
{
parentBuilder = parentBuilder.ParentBuilder;
}
return parentBuilder;
}
public DoorBuilder WithDoor()
{
return new DoorBuilder(GetParentBuilder());
}
public CarBuilderWithSyntax WithEngine(int cmq)
{
if (ParentBuilder != null)
{
return GetParentBuilder().WithEngine(cmq);
}
// Save somewhere this information
return this;
}
public Car Build()
{
return null;
}
public class DoorBuilder : CarBuilderWithSyntax
{
public DoorBuilder(CarBuilderWithSyntax builder)
: base(builder)
{
}
protected new DoorBuilder GetParentBuilder()
{
DoorBuilder parentBuilder = this;
while ((parentBuilder.ParentBuilder as DoorBuilder) != null)
{
parentBuilder = parentBuilder.ParentBuilder as DoorBuilder;
}
return parentBuilder;
}
public DoorBuilder HavingSide(Sides side)
{
// Save side this information somewhere
return GetParentBuilder();
}
public WindowBuilder WithWindow()
{
return new WindowBuilder(this);
}
public class WindowBuilder : DoorBuilder
{
public WindowBuilder(DoorBuilder builder)
: base(builder)
{
}
public WindowBuilder HavingWidth(int width)
{
// Terminal elements don't need to do the GetParentBuilder()
return this;
}
public WindowBuilder HavingHeight(int width)
{
// Terminal elements don't need to do the GetParentBuilder()
return this;
}
}
}
}
现在您只需要选择保存Builder
信息的方式/位置...注意各个类如何互连,以及各种GetParentBuilder()
使用。
var car = CarBuilderWithSyntax.Create()
.WithDoor()
.HavingSide(Sides.Left)
.WithWindow()
.HavingWidth(50)
.HavingHeight(50)
.WithEngine(100)
.Build();