看看Joshua Bloch在java中做构建器模式的方式,我有这个类:
public class NutritionFacts {
private final int calories;
private final int fat;
private final int sodium;
public static class Builder {
private int calories = 0;
private int fat = 0;
private int sodium = 0;
public Builder calories(int val)
{ calories = val; return this; }
public Builder fat(int val)
{ fat = val; return this; }
public Builder carbohydrate(int val)
{ carbohydrate = val; return this; }
public Builder sodium(int val)
{ sodium = val; return this; }
public NutritionFacts build() {
return new NutritionFacts(this);
}
}
private NutritionFacts(Builder builder) {
calories = builder.calories;
fat = builder.fat;
sodium = builder.sodium;
}
}
我可以以这种方式调用它来实例化营养事实对象:
NutritionFacts cocacola = new NutritionFacts.Builder().calories(140).build()
还有一个细微的变化,我可以有这个类:
public class NutritionFacts {
private final int calories;
private final int fat;
private final int sodium;
public static class Builder {
private int calories = 0;
private int fat = 0;
private int sodium = 0;
private Builder(){
}
public Builder calories(int val)
{ calories = val; return this; }
public Builder fat(int val)
{ fat = val; return this; }
public Builder carbohydrate(int val)
{ carbohydrate = val; return this; }
public Builder sodium(int val)
{ sodium = val; return this; }
public NutritionFacts build() {
return new NutritionFacts(this);
}
}
public static Builder builder(){
return new Builder()
}
private NutritionFacts(Builder builder) {
calories = builder.calories;
fat = builder.fat;
sodium = builder.sodium;
}
}
现在我可以这样做来创建NutritionFacts的实例:
NutritionFacts cocacola = NutritionFacts.builder().calories(140).build()
应用构建器模式的首选方法应该是什么?提到的两种方法在结果方面是否完全相同(干净、不变、ecc(。第二种方法有什么问题吗?
我想听听您的专家意见。
第二个在现有代码中更为常见。它们几乎完全相同,所以很难争论这两种形式的基本风格,除了我想第二种形式都更短,并且使用更少的外来语言功能(调用内部构造函数非常奇特,我猜(。请注意,某些 IDE 配置会自动尝试通过添加:顶部的import com.foo.yourpackage.NutritionFacts.Builder;
并将代码转换为:new Builder().calories(140).build();
来"帮助您",这也不是您想要的。此外,在仔细阅读NutritionFacts
类的 javadoc 时,可能不清楚如何使用第一种形式制作一个;而如果有明确的静态builder()
方法,我会立即看到。
所以这是支持第二种形式的 3 个原因,我真的找不到任何赞成第一种形式的东西,除了 API 作者少了一种编写方法。
但是,这也不是一个论点:您可以使用龙目岛的@Builder
功能自动生成所有这些东西。它生成第二种形式。