Android 编码规范:(二)遇到多个构造器参数时要考虑用构建器

静态工厂和构造器有个共同的局限性:它们都不能很好地扩展到大量的可选参数。考虑用一个类表示包装食品外面显示的营养成分标签。这些标签中有几个域是必须的:每份的含量、每罐的含量以及每份的卡路里,还有超过20个可选域:总脂肪量、饱和脂肪量、转化脂肪、胆固醇、钠等等。大多数产品在某几个可选域中都会有非零的值。

对于这样的类,应该用哪种构造器或者静态方法来编写呢?

1. 重叠构造器模式

  1. // Telescoping constructor pattern - does not scale well!    
  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. }  

2. JavaBeans模式

3. Builder模式,既能保证安全性,又能保证可读性。

  1. // Builder Pattern   
  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模式的客户端代码将更易于阅读和编写,构造器也比JavaBeans更加安全。



posted on 2012-05-28 14:59  springside例子  阅读(176)  评论(0编辑  收藏  举报