创建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》
 

Java对象创建模式的更多相关文章

  1. 设计模式---对象创建模式之原型模式(prototype)

    一:概念 原型模式(Prototype Pattern) 实际上就是动态抽取当前对象运行时的状态 Prototype模式是一种对象创建型模式,它采取复制原型对象的方法来创建对象的实例.使用Protot ...

  2. 深入理解JavaScript系列(48):对象创建模式(下篇)

    介绍 本篇主要是介绍创建对象方面的模式的下篇,利用各种技巧可以极大地避免了错误或者可以编写出非常精简的代码. 模式6:函数语法糖 函数语法糖是为一个对象快速添加方法(函数)的扩展,这个主要是利用pro ...

  3. 深入学习Java对象创建的过程:类的初始化与实例化

    在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的.在实例化一个对象时,JVM首先会检查相关类型是否已经加载并初始化,如果没有,则JVM立即进行加载并调用类构造器完 ...

  4. 《JavaScript 模式》读书笔记(5)— 对象创建模式4

    我们学完了大部分对象创建模式相关的内容,下面还有一些小而精的部分. 七.对象常量 JavaScript中没有常量的概念,虽然许多现代的编程环境可能为您提供了用以创建常量的const语句.作为一种变通方 ...

  5. 《JavaScript模式》第5章 对象创建模式

    @by Ruth92(转载请注明出处) 第5章:对象创建模式 JavaScript 是一种简洁明了的语言,并没有其他语言中经常使用的一些特殊语法特征,如 命名空间.模块.包.私有属性 以及 静态成员 ...

  6. 《Javascript模式》之对象创建模式读书笔记

    引言: 在javascript中创建对象是很容易的,可以使用对象字面量或者构造函数或者object.creat.在接下来的介绍中,我们将越过这些方法去寻求一些其他的对象创建模式. 我们知道js是一种简 ...

  7. 设计模式---对象创建模式之工厂方法模式(Factory Method)

    前提:“对象创建”模式 通过“对象创建”模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定.它是接口抽象之后的第一步工作. 典型模式(表现最为突出) 工 ...

  8. C++设计模式 之 “对象创建”模式:Factory Method、Abstract Factory、Prototype、Builder

    part 0 “对象创建”模式 通过“对象创建” 模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定.它是接口抽象之后的第一步工作. 典型模式 Fact ...

  9. 深入理解JavaScript系列(47):对象创建模式(上篇)

    介绍 本篇主要是介绍创建对象方面的模式,利用各种技巧可以极大地避免了错误或者可以编写出非常精简的代码. 模式1:命名空间(namespace) 命名空间可以减少全局命名所需的数量,避免命名冲突或过度. ...

随机推荐

  1. upd套接字服务器与客户端交互C++代码示范

    upd套接字服务器与客户端交互C++代码示范 // vc2_2_4UDPserver_Txwtech.cpp : 定义控制台应用程序的入口点. //服务器端 #include "StdAfx ...

  2. gdb基本命令总结

    本文介绍使用gdb调试程序的常用命令.  主要内容: [简介] [举例] [其他] [简介]  ============= GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具.如果你是在 ...

  3. Linux Pam后门总结拓展

    首发先知社区: https://xz.aliyun.com/t/7902 前言 渐渐发现pam后门在实战中存在种植繁琐.隐蔽性不强等缺点,这里记录下学习pam后门相关知识和pam后门的拓展改进. 0x ...

  4. Elasticsearch修改分词器以及自定义分词器

    Elasticsearch修改分词器以及自定义分词器 参考博客:https://blog.csdn.net/shuimofengyang/article/details/88973597

  5. vueX基础知识点笔记

    vuex是专门用来管理vue.js应用程序中状态的一个插件.他的作用是将应用中的所有状态都放在一起, 集中式来管理.需要声明的是,这里所说的状态指的是vue组件中data里面的属性.简单的来说, 它就 ...

  6. java List的初始化

    今天在处理生成excel的时候用到了java的list,但是需要直接赋值固定的几个变量,如果先初始化然后add的方法: List<String> name = new ArrayList( ...

  7. 【数位dp】CF 55D Beautiful numbers

    题目 Volodya is an odd boy and his taste is strange as well. It seems to him that a positive integer n ...

  8. C# 接口(interface) 抽象类(abstract)

    类代码: interface Employee { void ShowEmp(); } abstract class EmployeeInPostion: Employee { public abst ...

  9. 再探JVM内存模型

    以前学JVM的时候看过<深入理解JVM>,当时看的很模糊也记了些笔记,更像是为了应付面试.事实是确实把笔记都背上了,春招找实习的时候,内存管理.类加载.垃圾回收三连背一遍.后来自己做项目的 ...

  10. Tomcat的介绍

    Tomcat简介 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选. 支持Se ...