zoukankan      html  css  js  c++  java
  • 遇到多个构造器参数时要考虑用构建器

         考虑用一个类表示包装食品外面显示的营养成分标签,这些标签中有几个域是必需的:每份的含量,每罐的含量以及每份的卡路里,还有一些可选域:钠,歆,铁,总脂肪含量等等!下面以四个可选域举例。

        一般大家习惯采用重叠构造器模式:

     1 public class NutritionFacts1 {
     2 
     3     private final int servingSize;
     4     private final int servings;
     5     private final int calories;
     6     private final int fat;
     7     private final int sodium;
     8     private final int carbohydrate;
     9     
    10     public NutritionFacts1(int servingSize,int servings){
    11         this(servingSize,servings,0);
    12     }
    13     
    14     public NutritionFacts1(int servingSize,int servings,int calories){
    15         this(servingSize,servings,calories,0);
    16     }
    17     
    18     public NutritionFacts1(int servingSize,int servings,int calories,int fat){
    19         this(servingSize,servings,calories,fat,0);
    20     }
    21     
    22     public NutritionFacts1(int servingSize,int servings,int calories,int fat,int sodium){
    23         this(servingSize,servings,calories,fat,sodium,0);
    24     }
    25     
    26     public NutritionFacts1(int servingSize,int servings,
    27             int calories,int fat,int sodium,int carbohydrate){
    28         this.servingSize=servingSize;
    29         this.servings=servings;
    30         this.calories=calories;
    31         this.fat=fat;
    32         this.sodium=sodium;
    33         this.carbohydrate=carbohydrate;
    34     }
    35     
    36 }
     1 public class BuilderTest {
     2 
     3     public static void main(String[] args) {
     4 
     5         NutritionFacts1 nf1 = new NutritionFacts1(240,8,100,0,35,27);
     6         System.out.println(nf1.toString());
     7     
     8     }
     9 
    10 }

    这仅仅是6个参数,一旦参数增加,问题就来了!客户端代码会很难写,并且比较难以阅读!

         第二种方法是JavaBeans模式:

     1 public class NutritionFacts2 {
     2 
     3     private  int servingSize = -1;
     4     private  int servings = -1;
     5     private  int calories = 0;
     6     private  int fat = 0;
     7     private  int sodium = 0;
     8     private  int carbohydrate = 0;
     9     
    10     public NutritionFacts2(){}
    11     
    12     public void setServingSize(int servingSize){
    13         this.servingSize = servingSize;
    14     }
    15     public void setServings(int servings){
    16         this.servings = servings;
    17     }
    18     public void setCalories(int calories){
    19         this.calories = calories;
    20     }
    21     public void setFat(int fat){
    22         this.fat = fat;
    23     }
    24     public void setSodium(int sodium){
    25         this.sodium = sodium;
    26     }
    27     public void setCarbohydrate(int carbohydrate){
    28         this.carbohydrate = carbohydrate;
    29     }
    30     
    31 }
     1 public class BuilderTest {
     2 
     3     public static void main(String[] args) {
     4 
     5         NutritionFacts2 nf2 = new NutritionFacts2();
     6         nf2.setServingSize(10);
     7         nf2.setServings(20);
     8         nf2.setCalories(1);
     9         nf2.setCarbohydrate(5);
    10         nf2.setFat(0);
    11         nf2.setSodium(10);
    12     
    13     }
    14 
    15 }

    JavaBeans模式的缺点:

                                1,构造的过程分到了几个调用中,在构造JavaBeans的时候可能会不一致。

                                2,类无法仅仅通过检验构造器参数的有效性来保证一致性!

                                3,对象的不一致会导致失败,JavaBeans模式阻止了把类做为不可变的可能,需要程序员做额外努力来保证它线程安全。

    但是大部分的时候JavaBean是在线程中new出来的,只会供单线程使用,很少会出现多个线程共享JavaBean的情况!

          第三种方法Builder模式,既保证了像重叠构造器模式那样的安全,也能保证像JavaBeans模式那么好的可读性!

     1 public class NutritionFacts {
     2 
     3     private final int servingSize;
     4     private final int servings;
     5     private final int calories;
     6     private final int fat;
     7     private final int sodium;
     8     private final int carbohydrate;
     9     
    10     public static class Builder {
    11         private int servingSize;
    12         private int servings;
    13         
    14         private int calories = 0;
    15         private int fat = 0;
    16         private int sodium = 0;
    17         private int carbohydrate = 0;
    18         
    19         public Builder(int servingSize,int servings){
    20             this.servingSize=servingSize;
    21             this.servings=servings;
    22         }
    23         
    24         public Builder calories(int val){
    25             calories=val;
    26             return this;
    27         }
    28         public Builder fat(int val){
    29             fat=val;
    30             return this;
    31         }
    32         public Builder sodium(int val){
    33             sodium=val;
    34             return this;
    35         }
    36         public Builder carbohydrate(int val){
    37             carbohydrate=val;
    38             return this;
    39         }
    40         
    41         public NutritionFacts build(){
    42             return new NutritionFacts(this);
    43         }
    44     }
    45     
    46     private NutritionFacts(Builder builder){
    47         servingSize =  builder.servingSize;
    48         servings = builder.servings;
    49         calories = builder.calories;
    50         fat = builder.fat;
    51         sodium = builder.sodium;
    52         carbohydrate = builder.carbohydrate;
    53         
    54     }
    55     
    56 }
    1 public class BuilderTest {
    2 
    3     public static void main(String[] args) {
    4 
    5         NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).carbohydrate(4).sodium(5).carbohydrate(6).build();
    6     
    7     }
    8 
    9 }
  • 相关阅读:
    C语言面向对象编程(五):单链表实现(转)
    pthread_barrier_init,pthread_barrier_wait简介(转)
    Linux信号(signal) 机制分析(转)
    Linux 进程间通信 --- 信号通信 --- signal --- signal(SIGINT, my_func); --- 按键驱动异步通知(转)
    Linux 多线程环境下 进程线程终止函数小结(转)
    批量杀进程 ps awk grep
    C++中的INL(转)
    gdb调试多进程和多线程命令(转)
    转: 基于netty+ protobuf +spring + hibernate + jgroups开发的游戏服务端
    转:全栈工程师的知识栈列表
  • 原文地址:https://www.cnblogs.com/sqy123/p/6961786.html
Copyright © 2011-2022 走看看