Java Builder Pattern 实现,哪一个更好?



看看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功能自动生成所有这些东西。它生成第二种形式。

相关内容

最新更新