我们在平常类的构建过程中,可能会面临很多问题,可扩张性、安全性等等。想象一下,这样一个场景,我们现在要创建一个类,其中有6个属性,其中又有4个属性的值是不太确定的(可能某个对象就不需要其中的某个值),这时我们怎么创建这个类呢?以下是几种方法:

使用普通构造器

 public class Test {
private int servingSize;
private int servings;
private int calories;
private int fat;
private int sodium;
private int carbohydrate; public Test(int servingSize, int servings) {
this.servingSize = servingSize;
this.servings = servings;
this.calories = 0;
} public Test(int servingSize, int servings, int calories) {
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
this.fat = 0;
} public Test(int servingSize, int servings, int calories, int fat) {
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
this.fat = fat;
this.sodium = 0;
} public Test(int servingSize, int servings, int calories, int fat, int sodium) {
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
this.fat = fat;
this.sodium = sodium;
this.carbohydrate = 0;
} public Test(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) {
Test test = new Test(1,2,3,0,5,6);
}

如上所示,在实例化对象时,我们需要传入相应的值,这时发现:

  1. 第四个参数不是我们需要的,但是还不得不给他传递一个值
  2. 我们在传值时,很容易出错,某两个参数值互换了位置,这在工作时是不好发现的,但是程序会报错

所以上面的方式在涉及到参数比较多,而且参数值不太确定是否需要时,这种方法会给我们的编码以及后期维护带来很大的困扰,我们再改进一下。

JavaBeans模式

 public class Test {
private int servingSize;
private int servings;
private int calories;
private int fat;
private int sodium;
private int carbohydrate; public Test() { } 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;
} }

如上,我们先创建一个无参构造方法(可以不写出来,会默认创建),接下来就是利用setter方法给属性赋值

 public static void main(String[] args) {
Test test = new Test();
test.setServingSize(1);
test.setCalories(2);
test.setCalories(3);
test.setSodium(5);
test.setCarbohydrate(6);
}

如上,我们需要的对象不需要fat属性,我们就不用给其赋值,这中方法有几个好处:

  1. 客户端调用简单,也就是实例化对象的过程十分简单,并且不会出现把值传递出错的风险
  2. 别人能够很好的使用且理解简单

但是我们知道,javaBeans有个缺点:

  1. 线程不安全,因为对象的创建分在了好几步的过程中,不能保证对象状态的一致性

我们可以确保线程的安全,这就需要我们额外的精力(我们可以在对象构造完成,并且不允许在冻结之前使用时,手动冻结,实际中很少使用,编译器无法确定我们是否调用的freeze方法
)。因此这种方法也不够理想,还有什么继续改进的地方吗?

构建器(建造者模式的一种形式)

 public class Test {
private int servingSize;
private int servings;
private int calories;
private int fat;
private int sodium;
private int 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 calories) {
calories = calories;
return this;
} public Builder fat(int fat) {
fat = fat;
return this;
} public Builder sodium(int sodium) {
sodium = sodium;
return this;
} public Builder carbohydrate(int carbohydrate) {
carbohydrate = carbohydrate;
return this;
} public Test builder () {
return new Test(this);
}
} private Test(Builder builder) {
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
fat = builder.fat;
sodium = builder.sodium;
carbohydrate = builder.carbohydrate;
}
}

调用方式:

 public static void main(String[] args) {
Test test = new Builder(1,2).calories(3).fat(4).sodium(5).carbohydrate(6).builder();
}

这样就保证了对象在不变的情况下,简单明了地实现了对象实例化(至于代码中的内部类,我们以后细说)。

Java构造器与构建器的使用的更多相关文章

  1. java构造器和构建器

    本文摘自:https://blog.csdn.net/wh2827991/article/details/79013115 在实例化一个类的过程中,通常会遇到多个参数的构造函数,但如果有些参数是非必需 ...

  2. 深入探索Java设计模式之构建器模式(五)

    抽丝剥茧 细说架构那些事——[优锐课] 简单的程序不需要大量的设计过程,因为它们只关注有限的解决方案,仅使用几个类.大型程序专注于广泛的设计,该设计比好的设计范例的任何其他属性都更能利用可重用性.宏伟 ...

  3. Java基础——字符串构建器

    StringBuilder类: 可以将许多小段的字符串构建一个字符串. StringBuilder builder = new StringBuilder(); //构造一个空的字符串构建器 buil ...

  4. effective java之使用构建器来创建对象

    第二章第2条:遇到多个构造器参数时要考虑使用构建器(builder) 就是建造者模式(不直接生成想要的对象,而是让客户端利用所有有必要的参数调用构造器或者静态工厂)直接上代码 package com. ...

  5. 【转】通过lombok带你读透Builder构建器

    原地址:https://www.jianshu.com/p/0d8fc3df3647?from=timeline&isappinstalled=0 很久之前,我在<effective j ...

  6. Java 构造器 遇到多个构造器时要考虑用构建器

    静态工厂和构造器有个共同的局限性:它们都不能很好地扩展到大量的可选参数. 当一个类中有若干个必选属性和多个可选属性时,采用重叠构造器模式.JavaBeans模式或者Builder模式,但各有优劣. 当 ...

  7. 【读书笔记 - Effective Java】02. 遇到多个构造器参数时要考虑用构建器

    类有多个可选参数的解决方案: 1. 重叠构造器模式可行,但是当有许多参数的时候,客户端代码会很难编写,并且仍然较难以阅读. 2. JavaBeans模式,调用一个无参构造器来创造对象,然后调用sett ...

  8. Java构建器(多个构造器参数)

    今天看netty权威指南,第一次听说构建器,百度了几个博客,但是并没有通俗易懂一点儿的,综合别人的博客,总结如下: 1. 构建器是什么? 当创建对象需要传入多个参数的时候我们通常会根据参数的数量写不同 ...

  9. Effective JAVA 创建和销毁对象 遇到多参构造器考虑使用构建器

    //构建器抽象类,为不同类的实现提供 public interface Builder<T> { public T build(); } /** * @描述: 营养表 */ public ...

随机推荐

  1. Cmake用法

    目录 1,Cmake introduce 1.1 常用的目录结构 2,CMakeLists.txt文件的写法 Cmake 常用命令 Scripting Commands set include Pro ...

  2. Angular2 ng2-smart-table

    ng2-smart-table 入门 安装 你要做的就是运行以下命令: npm install --save ng2-smart-table 此命令将创建在你的`package.json`文件和安装包 ...

  3. 二、jspxcms使用-用户和模型

    原本想二次开发,后来放弃了,里面东西很多. 1.用户 菜单位置:用户权限 注意:用户中 id为0和1的用户为默认用户,不要删,0是默认管理员用户,1是匿名账户.                   会 ...

  4. 查看历史会话等待事件对应的session信息

    此处以enq: TX - row lock contention等待时间为例. 查看snap_id对应时间 select to_char(s.startup_time,'dd Mon "at ...

  5. GMT\UTC YYYY-MM-DDTHH:mm:ss.sssZ、YYYY-MM-DDTHH:mm:ss.sss+8:00意义及与北京时间转换

    UTC: Universal Time Coordinated 协调世界时,又称世界标准时间. GMT: Greenwich Mean Time 格林尼治平均时. 格林尼治标准时间的正午是指当太阳横穿 ...

  6. match 和 lastIndex 字符串检测差异

    match .replace .search 这写不能识别特殊字符 indexOf .indexof 能识别特殊字符 str.lastIndexOf('a') > -1 // 通过lastInd ...

  7. 游戏全区全服和分区分服 QQ斗地主的设计

    游戏全区全服和分区分服  QQ斗地主的设计 https://cloud.tencent.com/community/article/164816001481011910?fromSource=gwzc ...

  8. 设置js的ctx

    <script type="text/javascript" src="${ctx}/js/dynamic.jsp"></script> ...

  9. IO多路复用之select,poll,epoll个人理解

    在看这三个东西之前,先从宏观的角度去看一下,他们的上一个范畴(阻塞IO和非阻塞IO和IO多路复用) 阻塞IO:套接口阻塞(connect的过程是阻塞的).套接口都是阻塞的. 应用程序进程-----re ...

  10. Java bean 转 Map

    Java bean 转 Map 时需要使用Fastjson //方法 一 Map<String, Object> a = (Map<String, Object>)JSON.t ...