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

重叠构造器模式可行,但是当有许多参数的时候,客户端代码会难以编写,并且仍然较难以阅读。--他的前提是,有很多种不同的构造器情况,也就是很多构造器参数不同,或者说(很多参数可选,因为很多参数有默认值)。 
错误示例:
  1. // Telescoping constructor pattern - does not scale well! - Pages 11-12  
  2.   
  3. public class NutritionFacts {  
  4.     private final int servingSize;   // (mL)            required  
  5.     private final int servings;      // (per container) required  
  6.     private final int calories;      //                 optional  
  7.     private final int fat;           // (g)             optional  
  8.     private final int sodium;        // (mg)            optional  
  9.     private final int carbohydrate;  // (g)             optional  
  10.   
  11.     public NutritionFacts(int servingSize, int servings) {  
  12.         this(servingSize, servings, 0);  
  13.     }  
  14.   
  15.     public NutritionFacts(int servingSize, int servings,  
  16.             int calories) {  
  17.         this(servingSize, servings, calories, 0);  
  18.     }  
  19.   
  20.     public NutritionFacts(int servingSize, int servings,  
  21.             int calories, int fat) {  
  22.         this(servingSize, servings, calories, fat, 0);  
  23.     }  
  24.   
  25.     public NutritionFacts(int servingSize, int servings,  
  26.             int calories, int fat, int sodium) {  
  27.         this(servingSize, servings, calories, fat, sodium, 0);  
  28.     }  
  29.   
  30.     public NutritionFacts(int servingSize, int servings,  
  31.            int calories, int fat, int sodium, int carbohydrate) {  
  32.         this.servingSize  = servingSize;  
  33.         this.servings     = servings;  
  34.         this.calories     = calories;  
  35.         this.fat          = fat;  
  36.         this.sodium       = sodium;  
  37.         this.carbohydrate = carbohydrate;  
  38.     }  
  39.   
  40.     public static void main(String[] args) {  
  41.         NutritionFacts cocaCola =  
  42.             new NutritionFacts(240810003527);  
  43.     }  
  44. }  

替代方法:使用JavaBeans模式
  1. // JavaBeans Pattern - allows inconsistency, mandates mutability - Pages 12-13  
  2.   
  3. public class NutritionFacts {  
  4.     // Parameters initialized to default values (if any)  
  5.     private int servingSize  = -1;  // Required; no default value  
  6.     private int servings     = -1;  //     "     "     "      "  
  7.     private int calories     = 0;  
  8.     private int fat          = 0;  
  9.     private int sodium       = 0;  
  10.     private int carbohydrate = 0;  
  11.   
  12.     public NutritionFacts() { }  
  13.   
  14.     // Setters  
  15.     public void setServingSize(int val)  { servingSize = val; }  
  16.     public void setServings(int val)     { servings = val; }  
  17.     public void setCalories(int val)     { calories = val; }  
  18.     public void setFat(int val)          { fat = val; }  
  19.     public void setSodium(int val)       { sodium = val; }  
  20.     public void setCarbohydrate(int val) { carbohydrate = val; }  
  21.   
  22.   
  23.     public static void main(String[] args) {  
  24.         NutritionFacts cocaCola = new NutritionFacts();  
  25.         cocaCola.setServingSize(240);  
  26.         cocaCola.setServings(8);  
  27.         cocaCola.setCalories(100);  
  28.         cocaCola.setSodium(35);  
  29.         cocaCola.setCarbohydrate(27);  
  30.     }  
  31. }  

本节建议使用的是Builder模式:
  1. // Builder Pattern - Pages 14-15  
  2.   
  3. public class NutritionFacts {  
  4.     private final int servingSize;  
  5.     private final int servings;  
  6.     private final int calories;  
  7.     private final int fat;  
  8.     private final int sodium;  
  9.     private final int carbohydrate;  
  10.   
  11.     public static class Builder {  
  12.         // Required parameters  
  13.         private final int servingSize;  
  14.         private final int servings;  
  15.   
  16.         // Optional parameters - initialized to default values  
  17.         private int calories      = 0;  
  18.         private int fat           = 0;  
  19.         private int carbohydrate  = 0;  
  20.         private int sodium        = 0;  
  21.   
  22.         public Builder(int servingSize, int servings) {  
  23.             this.servingSize = servingSize;  
  24.             this.servings    = servings;  
  25.         }  
  26.   
  27.         public Builder calories(int val)  
  28.             { calories = val;      return this; }  
  29.         public Builder fat(int val)  
  30.             { fat = val;           return this; }  
  31.         public Builder carbohydrate(int val)  
  32.             { carbohydrate = val;  return this; }  
  33.         public Builder sodium(int val)  
  34.             { sodium = val;        return this; }  
  35.   
  36.         public NutritionFacts build() {  
  37.             return new NutritionFacts(this);  
  38.         }  
  39.     }  
  40.   
  41.     private NutritionFacts(Builder builder) {  
  42.         servingSize  = builder.servingSize;  
  43.         servings     = builder.servings;  
  44.         calories     = builder.calories;  
  45.         fat          = builder.fat;  
  46.         sodium       = builder.sodium;  
  47.         carbohydrate = builder.carbohydrate;  
  48.     }  
  49.   
  50.     public static void main(String[] args) {  
  51.         NutritionFacts cocaCola = new NutritionFacts.Builder(2408).  
  52.             calories(100).sodium(35).carbohydrate(27).build();  
  53.     }  
  54. }  

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

但是,当大多数参数都是可选的时候,Builder模式就是一个不错的选择。(比如好多框架就用的这种方式:类的构造器或者静态工厂中具有多个参数)
 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值