美文网首页
Java 构建器

Java 构建器

作者: EvilsoulM | 来源:发表于2015-10-25 19:34 被阅读326次

遇到多个构造器参数时要考虑用构建器

考虑用一个类表示包装食品外面显示的营养成分标签。这些标签中有几个域是必须的:每分的含量,每罐的含量以及每份的卡路里,还有超过20个可选域。对于这样一个类,应该选用那种构造器或者静态方法来编写呢?我们一向习惯采取重叠构造器模式。

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

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

这种构造器通常需要许多你不想设置的参数,但是还不得不为他们传递值。在这个例子中,我们就给fat传递了0。如果仅仅6个参数,看起来还不算太糟,问题是随着参数的增加,他们很快就失去了控制。

遇到许多构造起参数的时候,还有第二种替代的办法,即javaBeans模式,在这个模式下,调用一个无参构造器来创造对象,然后调用setter方法来设置每个必须的参数,以及每个相关的可选参数:

    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 NutritionFacts(){}
      
      //Setters
      public void setServingSize(int val){servingSize=val;}
      //........就不多写了
    }

遗憾的是,JavaBeans模式自身有着很严重的缺点。因为构造过程被分到几个调用中,在构造过程中JavaBean可能处于非一致的状态。JavaBeans模式阻止了把类做成不可变的可能,这就需要程序员付出额外的努力来确保他的线程安全。

幸运的是,还有第三种代替方法,既能保证像重叠构造器模式那样的安全性,也能保证像JavaBeans模式那么好的可读性。这就是Builder模式的一种形式。不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器(或者静态工厂),得到一个builder对象。然后客户端在builder对象上调用类似于setter的方法,来设置每个相关的可选参数。最后,客户端调用无参的build方法来生成不可变的对象。

    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{
        private final int servingSize;//必要
        private final int servings;//必要
        private final int calories=0;//可选
        private final int fat=0;//可选
        private final int sodium=0;//可选
        private final int carbohydrate=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 NutritionFacts build(){
          return new NutritionFacts(this);
        }
      }

       private NutritionFacts(Builder builder){
         this.servingSize=builder.servingSize;
         this.servings=builder.servings;
         this.calories=builder.calories;
         this.fat=builder.fat;
         this.sodium=builder.sodium;
         this.carbohydrate=builder.carbohydrate;
      }
    }

构造的函数

NutritionFacts cacaCola=new NutritionFacts.Builder(240,9).calories(100).sodium(23).build();

相关文章

  • Effective Java中构建器Builder的理解

    在Effective Java中, 有对构建器的讲解, 看了 java中Builder构建器的理解 之后, 了解...

  • Java 构建器

    遇到多个构造器参数时要考虑用构建器 考虑用一个类表示包装食品外面显示的营养成分标签。这些标签中有几个域是必须的:每...

  • Java-构建器

    需求: 创建Bean实例时需要传入多个参数 需要控制参数的访问权限,防止被其他使用者修改 能够做参数有效性检查 构...

  • java并发编程之AbstractQueuedSynchroni

    引言 AbstractQueuedSynchronizer,队列同步器,简称AQS,它是java并发用来构建锁或者...

  • 2020-02-19 JVM内存结构分析

    java运行机制 java虚拟机构建在操作系统之上,java文件可以用JDK自带的java编译器(javac)编译...

  • 构建第一个SpringBoot项目

    构建须知 预先善其事,必先利其器。要想构建springboot项目,必须先熟悉工具 springboot是java...

  • JAVA AQS结构及其原理分析

    引言 AQS,即AbstractQueuedSynchronizer, 队列同步器,它是Java并发用来构建锁和其...

  • 对于AQS的理解

    AQS,即AbstractQueuedSynchronizer, 抽象队列同步器,它是Java并发用来构建锁和其他...

  • iOS设计模式之Builder Pattern

    在阅读《Effective Java》时,其中的****第2条准则:遇到多个构造器参数时需要考虑用构建器。****...

  • 设计模式 - Builder 模式

    Effective Java 第2条:遇到多个构造器参数时要考虑使用构建器 三种创建对象的方式。 目录 重叠构造器...

网友评论

      本文标题:Java 构建器

      本文链接:https://www.haomeiwen.com/subject/fuqxhttx.html