读《Effective Java》总结第二条:构建器_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 读《Effective Java》总结第二条:构建器

读《Effective Java》总结第二条:构建器

 2014/7/21 21:38:30  黑龙0110  程序员俱乐部  我要评论(0)
  • 摘要:<divclass="iteye-blog-content-contain"style="font-size:16px">今天是讲《EffectiveJava》中的第二条:遇到多个构造器参数时要考虑用构建器这节我们先看代码(这些代码是我直接从书上抄下来的,这节的代码示例给的非常好)示例一:publicclassNutritionFacts{privatefinalintservingSize;//requiredprivatefinalintservings
  • 标签:总结 Java
<div class="iteye-blog-content-contain" style="font-size: 16px">
    今天是讲《Effective Java》中的第二条:遇到多个构造器参数时要考虑用构建器

    这节我们先看代码(这些代码是我直接从书上抄下来的,这节的代码示例给的非常好)

    示例一:


public class NutritionFacts{
    private final int servingSize;     //required
    private final int servings;        //required
    private final int calories;    //optional
    private final int fat;
    private final int sodium;
    private final int carbohydrate;

   public NutritionFacts(int servingSize , int servings){
              this(servingSize,servings,calories,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;

   }

}



 

那我们都是这么使用的:

NutritionFacts cocaCola= new NutritionFacts(240,8,100,0,0,27);

有些参数我们本来是不想设置的,但是又不得不给它们传值,于是给传个0。现在是6个参数,如果是10个或再多呢?对于客户端代码是很难写的,那如果有两参数你给记错了,传错值,那编译器也不会提示错误,到程序运行时出现了错误,那就更麻烦了。
使用JavaBean模式来替代:
public class NutritionFacts{
    private int servingSize=-1;     //required
    private int servings=-1;        //required
    private int calories=0;    //optional
    private int fat=0;
    private int sodium=0;
    private int carbohydrate=0;

public NutritionFacts(){}

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;}

}



调用时:
NutritionFacts cocaCola= new NutritionFacts();
cocaCola. setServingSize(240);
cocaCola. setServings(8);
cocaCola. setCalories(100);
cocaCola. setCarbohydrate(27);



JavaBean模式的缺点:构造过程中被分割到几个调用中,在构造过程中Javabean可能处于不一致状态。另外一点,JavaBean模式阻止了把类做成不可变的可能。

幸运有有下面这种:
public class NutritionFacts{
    private final int servingSize;     //required
    private final int servings;        //required
    private final int calories;    //optional
    private final int fat;
    private final int sodium;
    private final int carbohydrate;
    
    public static class Builder{

        private final int servingSize;    
    private final int servings;        


      private int calories=0;    //optional
      private int fat=0;
      private int sodium=0;
      private int carbohydrate=0;
     
      public Builder(int servingSize,int servings){
           this.servingSize = servingSize;
           this.serving=servings;
      }
      
      public Butilder calories(int val){
        calories=val; return this;
       }
public Butilder fat (int val){
        fat =val; return this;
       }
public Butilder sodium (int val){
        sodium =val; return this;
       }
public Butilder carbohydrate (int val){
        carbohydrate =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;
}

}


NutritionFacts cocaCola=new NutritionFacts.Builder(240,8).calories(100).carbohydrate(27).build();




build方法可以检验这些约束条件,将参数从bulider拷贝到对象中之后,并在对象域而不是buider域中对它们进行检验。


总结一下什么时候使用Builder模式呢?
    如果类的构造器或者静态工厂方法中具有多个参数,设计这种类时,Builder模式就是中不错的选择,特别是在大多数参数是可选的情况下。




</div>
发表评论
用户名: 匿名