您的位置:首页 > 其它

第2条:遇到多个构造器参数时要考虑用构建器

2011-12-09 18:57 543 查看
重叠构造器模式可行,但是当有许多参数的时候,客户端代码会难以编写,并且仍然较难以阅读。--他的前提是,有很多种不同的构造器情况,也就是很多构造器参数不同,或者说(很多参数可选,因为很多参数有默认值)。

错误示例:

view
plaincopy
to clipboardprint?

//
Telescoping constructor pattern - does not scale well! - Pages 11-12

public class NutritionFacts
{

private final int servingSize; //
(mL) required

private final int servings; //
(per container) required

private final int calories; //
optional

private final int fat; //
(g) optional

private final int sodium; //
(mg) optional

private final int carbohydrate; //
(g) optional

public NutritionFacts(int servingSize, int servings)
{

this(servingSize,
servings, 0);

}

public NutritionFacts(int servingSize, int servings,

int calories)
{

this(servingSize,
servings, calories, 0);

}

public NutritionFacts(int servingSize, int servings,

int calories, int fat)
{

this(servingSize,
servings, calories, fat, 0);

}

public NutritionFacts(int servingSize, int servings,

int calories, int fat, int sodium)
{

this(servingSize,
servings, calories, fat, sodium, 0);

}

public NutritionFacts(int servingSize, int servings,

int calories, int fat, int sodium, int carbohydrate)
{

this.servingSize =
servingSize;

this.servings
= servings;

this.calories
= calories;

this.fat =
fat;

this.sodium
= sodium;

this.carbohydrate
= carbohydrate;

}

public static void main(String[]
args) {

NutritionFacts
cocaCola =

new NutritionFacts(240, 8, 100, 0, 35, 27);

}

}

替代方法:使用JavaBeans模式

view
plaincopy
to clipboardprint?

//
JavaBeans Pattern - allows inconsistency, mandates mutability - Pages 12-13

public class NutritionFacts
{

//
Parameters initialized to default values (if any)

private int servingSize =
-1; //
Required; no default value

private int servings
= -1; //
" " " "

private int calories
= 0;

private int fat = 0;

private int sodium
= 0;

private int carbohydrate
= 0;

public NutritionFacts()
{ }

//
Setters

public void setServingSize(int val) {
servingSize = val; }

public void setServings(int val)
{ servings = val; }

public void setCalories(int val)
{ calories = val; }

public void setFat(int val) {
fat = val; }

public void setSodium(int val)
{ sodium = val; }

public void setCarbohydrate(int val)
{ carbohydrate = val; }

public static void main(String[]
args) {

NutritionFacts
cocaCola = new NutritionFacts();

cocaCola.setServingSize(240);

cocaCola.setServings(8);

cocaCola.setCalories(100);

cocaCola.setSodium(35);

cocaCola.setCarbohydrate(27);

}

}

本节建议使用的是Builder模式:

view
plaincopy
to clipboardprint?

//
Builder Pattern - Pages 14-15

public class NutritionFacts
{

private final int servingSize;

private final int servings;

private final int calories;

private final int fat;

private final int sodium;

private final int carbohydrate;

public static class Builder
{

//
Required parameters

private final int servingSize;

private final int servings;

//
Optional parameters - initialized to default values

private int calories = 0;

private int fat
= 0;

private int carbohydrate = 0;

private int sodium = 0;

public Builder(int servingSize, int servings)
{

this.servingSize
= servingSize;

this.servings =
servings;

}

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) {

servingSize =
builder.servingSize;

servings
= builder.servings;

calories
= builder.calories;

fat =
builder.fat;

sodium
= builder.sodium;

carbohydrate
= builder.carbohydrate;

}

public static void main(String[]
args) {

NutritionFacts
cocaCola = new NutritionFacts.Builder(240, 8).

calories(100).sodium(35).carbohydrate(27).build();

}

}

Builder方式不足:为了创建对象,必须先创建它的构建器。会有所开销。而且代码冗长。

但是,当大多数参数都是可选的时候,Builder模式就是一个不错的选择。(比如好多框架就用的这种方式:类的构造器或者静态工厂中具有多个参数)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: