是否可以编写遵循给定语法的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()
? 最佳答案
您可以执行以下操作:
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();