• Java对象创建模式


        创建Java对象时,对于可为空的属性,创建对象的时候有3种模式:重叠构造器模式、JavaBeans模式、Builder模式(推荐)、Stream模式(推荐)。


                                                                重叠构造器模式

     
         该模式使用多个构造器创建Java对象。
         该写法符合Java的标准惯例,但是随着参数的越来越多,代码变得越来越难写。而且该方式灵活性低,可读性较差,客户端想要知道哪些值的具体含义,还需要仔细数参数,而且还容易写错参数的位置。 
    package effectiveJava.builder;
    
    public class NutritionFactsMultiContr {
        //食物尺寸
        private int servingSize;
        //食物数量
        private int servings;
        //热量(卡路里)
        private int calories;
        //脂肪含量
        private int fat;
        //食用盐(钠)含量
        private int sodium;
        //糖类含量
        private int carbohydrate;
    
        public NutritionFactsMultiContr(int servingSize, int servings) {
            this(servingSize,servings,0);
        }
    
        public NutritionFactsMultiContr(int servingSize, int servings, int calories) {
            this(servingSize,servings,calories,0);
        }
    
        public NutritionFactsMultiContr(int servingSize, int servings, int calories, int fat) {
            this(servingSize,servings,calories,fat,0);
        }
    
        public NutritionFactsMultiContr(int servingSize, int servings, int calories, int fat, int sodium) {
            this(servingSize,servings,calories,fat,sodium,0);
        }
    
        public NutritionFactsMultiContr(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;
        }
    
        public static void main(String[] args) {
            NutritionFactsMultiContr nutritionFacts = new NutritionFactsMultiContr(1,2,3,4,5,6);
        }
    
    }
    

      


                                                        JavaBeans模式

         
          该模式通过调用一个无参构造器来创建对象,并使用setter方法来设置参数值。
          该模式弥补了重叠构造器模式的不足,而且创造实例很容易,代码的可读性也高。但是JavaBeans模式将构造过程分到几个步骤中,在构造过程中JavaBean可能处于不一致的状态,导致一些未知的错误。同时,JavaBeans模式阻止了把类做成不可变的可能。
    package effectiveJava.builder;
    //营养成分
    public class NutritionFactsSetter {
    
        //食物尺寸
        private int servingSize;
        //食物数量
        private int servings;
        //热量(卡路里)
        private int calories;
        //脂肪含量
        private int fat;
        //食用盐(钠)含量
        private int sodium;
        //糖类含量
        private int carbohydrate;
    
    
        public void setServingSize(int servingSize) {
            this.servingSize = servingSize;
        }
    
    
        public void setServings(int servings) {
            this.servings = servings;
        }
    
    
        public void setCalories(int calories) {
            this.calories = calories;
        }
    
    
        public void setFat(int fat) {
            this.fat = fat;
        }
    
    
        public void setSodium(int sodium) {
            this.sodium = sodium;
        }
    
    
        public void setCarbohydrate(int carbohydrate) {
            this.carbohydrate = carbohydrate;
        }
    
    
        public static void main(String[] args) {
            NutritionFactsSetter nutritionFacts = new NutritionFactsSetter();
            nutritionFacts.setCalories(1);
            nutritionFacts.setCarbohydrate(2);
        }
    }
    

      


                                                                           Builder模式

     
        该模式不直接生成想要的对象,而是先创建一个builder对象,再在builder上调用类似setter的方法设置参数值,最后调用无参的build方法来生成所需要的对象。(注意:Builder模式下,想要创建的对象的构造器是私有的,这样创建出来的对象是不可变的
         该模式既能像重叠构造器模式那样的安全性,也能保证像JavaBeans模式那样的可读性,同时实现了对象的不可变性。但是Builder模式为了创建对象,必须先创建它的构建器,导致代码有点冗余。
         Builder模式模拟了具名的可选参数。
    package effectiveJava.builder;
    //营养成分
    public class NutritionFacts {
    
    
        //食物尺寸
        private int servingSize;
        //食物数量
        private int servings;
        //热量(卡路里)
        private int calories;
        //脂肪含量
        private int fat;
        //食用盐(钠)含量
        private int sodium;
        //糖类含量
        private int carbohydrate;
    
        /**
         * NutritionFacts是不可变的,不对外提供构造器
         * @param builder
         */
        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;
        }
    
        public static class Builder {
            private int servingSize;
            private int servings;
            private int calories;
            private int fat;
            private int sodium;
            private int carbohydrate;
    
    
            //必填字段
            public Builder(int servingSize, int servings) {
                this.servingSize = servingSize;
                this.servings = servings;
            }
    
            //可选字段
            public Builder calories(int val){
                this.calories = val;
                return this;
            }
    
            public Builder fat(int val){
                this.fat = val;
                return this;
            }
    
            public Builder sodium(int val){
                this.sodium = val;
                return this;
            }
    
            public Builder carbohydrate(int val){
                this.carbohydrate = val;
                return this;
            }
    
            public NutritionFacts build() {
                return new NutritionFacts(this);
            }
        }
    
        public static void main(String[] args) {
            NutritionFacts facts = new NutritionFacts.Builder(1, 2).calories(3).fat(4).build();
        }
    }
    

      


                                                                        Stream模式

       
        Java8中引入了一种新特性Stream,这让编码变得更加简单易读(其实,该思想在以前的JDK版本中也有使用,例如:StringBuilder、StringBuffer)。在对象的创建过程中,我们也可以使用Stream思想。
        Stream模式就是将setter方法的返回值变为对象本身,这样就可以连续调用setter方法。
    package effectiveJava.builder;
    
    public class NutritionFactsStream {
        //食物尺寸
        private int servingSize;
        //食物数量
        private int servings;
        //热量(卡路里)
        private int calories;
        //脂肪含量
        private int fat;
        //食用盐(钠)含量
        private int sodium;
        //糖类含量
        private int carbohydrate;
    
        public NutritionFactsStream() {
        }
    
        public int getServingSize() {
            return servingSize;
        }
    
        public NutritionFactsStream setServingSize(int servingSize) {
            this.servingSize = servingSize;
            return this;
        }
    
        public int getServings() {
            return servings;
        }
    
        public NutritionFactsStream setServings(int servings) {
            this.servings = servings;
            return this;
        }
    
        public int getCalories() {
            return calories;
        }
    
        public NutritionFactsStream setCalories(int calories) {
            this.calories = calories;
            return this;
        }
    
        public int getFat() {
            return fat;
        }
    
        public NutritionFactsStream setFat(int fat) {
            this.fat = fat;
            return this;
        }
    
        public int getSodium() {
            return sodium;
        }
    
        public NutritionFactsStream setSodium(int sodium) {
            this.sodium = sodium;
            return this;
        }
    
        public int getCarbohydrate() {
            return carbohydrate;
        }
    
        public NutritionFactsStream setCarbohydrate(int carbohydrate) {
            this.carbohydrate = carbohydrate;
            return this;
        }
    
        public static void main(String[] args) {
            NutritionFactsStream nutritionFacts = new NutritionFactsStream().setServings(1).setServings(2);
        }
    }
    

     

          此外,创建对象的模式还有很多,比如:工厂模式、单例模式等,不是本文讨论的重点,有兴趣的可以自己研究一下。

    参考资料:

    • Joshua Bloch 《Effective Java》
     
  • 相关阅读:
    CSS3 not
    rxjs1
    Angular 2 组件之间如何通信?
    开发去。。
    补零补零
    MySQL数据库从复制及企业配置实践
    互联网中接口安全解决方案
    redis服务打不开--解决办法
    搭建Git服务器
    git将当前分支上修改的东西转移到新建分支
  • 原文地址:https://www.cnblogs.com/BlueStarWei/p/13335632.html
Copyright © 2020-2023  润新知