zoukankan      html  css  js  c++  java
  • 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》
     
  • 相关阅读:
    年末反思
    Flink运行时架构
    Phoenix 启动报错:Error: ERROR 726 (43M10): Inconsistent namespace mapping properties. Cannot initiate connection as SYSTEM:CATALOG is found but client does not have phoenix.schema.
    Clickhouse学习
    Flink简单认识
    IDEA无法pull代码到本地,Can't Update No tracked branch configured for branch master or the branch doesn't exist.
    第1章 计算机系统漫游
    简单的 Shell 脚本入门教程
    开源≠免费 常见开源协议介绍
    MySQL 视图
  • 原文地址:https://www.cnblogs.com/BlueStarWei/p/13335632.html
Copyright © 2011-2022 走看看