下面是我试过的代码,有更好的方法吗?
public class NutritionFacts
{
public static NutritionFacts.Builder Build(string name, int servingSize, int servingsPerContainer)
{
return new NutritionFacts.Builder(name, servingSize, servingsPerContainer);
}
public sealed class Builder
{
public Builder(String name, int servingSize,
int servingsPerContainer)
{
}
public Builder totalFat(int val) { }
public Builder saturatedFat(int val) { }
public Builder transFat(int val) { }
public Builder cholesterol(int val) { }
//... 15 more setters
public NutritionFacts build()
{
return new NutritionFacts(this);
}
}
private NutritionFacts(Builder builder) { }
protected NutritionFacts() { }
}
Run Code Online (Sandbox Code Playgroud)
我们如何扩展这样的课程?我们是否需要为每个派生类编写单独的构建器类?
public class MoreNutritionFacts : NutritionFacts
{
public new static MoreNutritionFacts.Builder Build(string name, int servingSize, int servingsPerContainer)
{
return new MoreNutritionFacts.Builder(name, servingSize, servingsPerContainer);
}
public new sealed class Builder
{
public Builder(String name, int servingSize,
int servingsPerContainer) {}
public Builder totalFat(int val) { }
public Builder saturatedFat(int val) { }
public Builder transFat(int val) { }
public Builder cholesterol(int val) { }
//... 15 more setters
public Builder newProperty(int val) { }
public MoreNutritionFacts build()
{
return new MoreNutritionFacts(this);
}
}
private MoreNutritionFacts(MoreNutritionFacts.Builder builder) { }
}
Run Code Online (Sandbox Code Playgroud)Jon*_*eet 23
在Protocol Buffers中,我们实现了这样的构建器模式(大大简化):
public sealed class SomeMessage
{
public string Name { get; private set; }
public int Age { get; private set; }
// Can only be called in this class and nested types
private SomeMessage() {}
public sealed class Builder
{
private SomeMessage message = new SomeMessage();
public string Name
{
get { return message.Name; }
set { message.Name = value; }
}
public int Age
{
get { return message.Age; }
set { message.Age = value; }
}
public SomeMessage Build()
{
// Check for optional fields etc here
SomeMessage ret = message;
message = null; // Builder is invalid after this
return ret;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这与EJ2中的模式不完全相同,但是:
StringBuilder
.Build()
保证不变性后,构建器变为无效.遗憾的是,它不能像EJ2版本那样用作一种"原型".this
了为了预C#3用户而返回的setter .我还没有真正研究过构建模式的继承 - 无论如何它都不支持Protocol Buffers.我怀疑这很棘手.
这篇博客文章可能会引起您的兴趣
C# 中该模式的一个巧妙变体是使用隐式转换运算符来使对 Build() 的最终调用变得不必要:
public class CustomerBuilder
{
......
public static implicit operator Customer( CustomerBuilder builder )
{
return builder.Build();
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4990 次 |
最近记录: |