1.问题背景
有这样一个背景:考虑到用一个类描述产品的成分说明书。在成分说明书中,某些标签是必需的:成分A,成分B,另外还有其他可选成分,成分C,成分D,成分E......对于这样的类,如果使用构造器来完成类对象的构造的话,是相当复杂的,因为你可能需要写许多的构造方法以满足不同产品的成分说明。
2.重叠构造器模式
在以上背景下,程序猿一般会采用重叠构造起模式。实例如下:
public class Product{
private final int proElem1;// 成份1,必需参数
private final int proElem2;//成份2,必需参数
private final int proElem3;//成份3,可选参数
private final int proElem4;//成份4,可选参数
public Product(int proElem1,int proElem2){
this.proElem1 = proElem1;
this.proElem2 = proElem2;
this(proElem1,proElem2,0,0);
}
public Product(int proElem1,int proElem2,int proElem3){
this(proElem1,proElem2,proElem3,0);
}
public Product(int proElem1,int proElem2,int proElem3,int proElem4){
this.proElem1 = proElem1;
this.proElem2 = proElem2;
this.proElem3 = proElem3;
this.proElem4 = proElem4;
}
}
你创建实例的时候就可以根据自己需要的参数创建不同的实例。上面的程序一定程序上可以使得创建实例更加清晰,但是想象一下如果类需要设置的参数特别多的情况,客户端代码会很难编写,而且比较难以阅读,如果客户端不小心颠倒了参数的顺序,编译器可能也不会出错。当遇到许多构造器参数的时候可以考虑以下方案。
3.JavaBeans模式
在这种模式下,使用一个无参的构造器来创建实例,然后使用属性的setter方法来设置属性的值,实例如下:
public class Product{
private int proElem1;
private int proElem2;
private int proElem3;
private int proElem4;
public Product(){
}
public void setProElem1(int proElem1){
this.proElem1 = proElem1;
}
public void setProElem2(int proElem2){
this.proElem2 = proElem2;
}
public void setProElem3(int proElem3){
this.proElem3 = proElem3;
}
public void setProElem4(int proElem4){
this.proElem4 = proElem4;
}
}
这种模式弥补了重叠构造器模式的不足,使得创建实例更加容易。
JavaBeans模式的缺点:实例的创建被分成了几个阶段,使得实例在程序中处于一种不一致的状态(我随时都可以设置实例的属性)。幸运的是,还有第三种方法!
3.建造者模式
建造者模式既可以像重叠构造器那么安全,又能保证像JavaBeans那样的可读性。使用Builder模式,不直接生成对象,而是让客户端利用必要的参数调用构造器,得到一个builder对象,然后在builder对象上调用类似setter的方法,来设置参数,实例如下:
public class Product{
private final int proElem1;
private final int proElem2;
private final int proElem3;
private final int proElem4;
public static class Builder{
private final int proElem1;
private final int proElem2;
private int proElem3;
private int proElem4;
public Builer(int proElem1,int proElem2){
this.proElem1 = proElem1;
this.proElem2 = proElem2;
}
public Builder proElem3(int proElem3){
this.proElem3 = proElem3;
return this;
}
public Builder proElem4(int proElem4){
this.proElem4 = proElem4;
return this;
}
public Product build(){
return new Product(this);
}
}
private Product(Builder builder){
proElem1 = builder.proElem1;
proElem2 = builder.proElem2;
proElem3 = builder.proElem3;
proElem4 = builder.proElem4;
}
}
使用Builder模式创建对象的优点:
1、客户端代码更容易编写,builder模式模拟了具名的可选参数,设置参数更加清晰;
2、通过build方法可以对参数进行约束,如果不满足条件可以抛出异常;
3、设置了参数的builder生成了一个很好的抽象工厂;
备注:定义一个范型就可以满足所有的builder
public interface Builder<T>{
public T build();
}
4.总结
如果类的构造器或者静态工厂中具有多个参数,设计这种类时,Builder模式是种不错的选择,特别是当大多数参数都是可选的时候。与传统的重叠构造器模式相比,使用Builder模式的客户端代码更易于阅读和编写,构建器也比JavaBeans更加安全。
版权声明:本文为博主原创文章,未经博主允许不得转载。
分享到:
相关推荐
2. **构建器(Builder pattern)**:当类有多个构造器参数时,构建器模式提供了一种更清晰的构造对象的方式,避免了“参数过多”的问题。 3. **单例模式**:通过私有构造器和枚举类型强化单例属性,确保线程安全且...
标题“effective-java.pdf”与描述“effective-java.pdf”表明本文档是关于Java编程实践的指南,且内容可能来自于一本名为《Effective Java》的书籍,该书是由Joshua Bloch编写,被广泛认为是Java编程的权威指南。...
《Effective Java》是Java开发领域的经典著作,由Joshua Bloch撰写,中文版第二版更是深受广大Java开发者喜爱。这本书提供了许多实用的编程实践和经验教训,帮助开发者编写出更高效、可维护的Java代码。这里我们将...
2. **构造器与工厂方法**:提倡使用私有构造器和静态工厂方法,以便于控制类的实例化过程,提高代码灵活性,例如实现不可变对象、延迟初始化等。 3. **接口与抽象类**:讨论了接口和抽象类在设计上的差异,强调接口...
3. **泛型**:第二版《Effective Java》详尽讨论了Java泛型,包括其基本概念、类型擦除、边界通配符、类型推断以及如何有效地使用泛型类和泛型方法。 4. **构造器**:书中阐述了如何设计和使用构造器来创建对象,...
《Effective Java》是Java编程领域的一本经典著作,由Joshua Bloch撰写,第二版发布于2008年。这本书旨在提供实用的编程指导,帮助开发者写出更高效、更可维护的Java代码。以下是对书中核心知识点的详细解读: 1. *...
通过这份全面的学习资料,初学者可以逐步构建自己的Java知识体系,为进一步深入学习和职业发展打下坚实的基础。 “新建文本文档.txt”可能是一个简单的文本文件,用于记录学习过程中的笔记或者资源链接,或者可能是...
18. **使用并发构建器来创建复杂对象**:在多线程环境下,使用并发构建器可以更安全高效地创建复杂对象。 19. **避免在equals()中使用instanceof**:在比较对象时,直接比较类型可能导致错误,应使用getClass()并...
学习Swing可以帮助理解事件处理、布局管理器以及各种组件的使用,如按钮、文本框等。 【多线程编程】 Java中的多线程编程是其核心特性之一。通过学习《Java线程》这样的书籍,可以理解线程的创建、同步、通信和线程...
#### 第二章 创建/销毁对象 ##### 用静态工厂方法代替构造器 在面向对象编程中,对象的创建通常是通过构造器来完成的。然而,在某些情况下,使用静态工厂方法来创建对象可能会更加灵活和高效。 **静态工厂方法的...
#### 二、《Effective Java》(第二版) 由Joshua Bloch编著的《Effective Java》被广大开发者誉为Java编程的最佳实践宝典。本书主要关注于如何编写高质量的Java代码,并提供了一系列实用的设计模式和最佳实践建议...
《Effective Java》是Java开发领域的经典著作,由Joshua Bloch撰写,第二版更是程序员们不可或缺的参考书籍。这本书深入探讨了如何编写出高质量、高效、可维护的Java代码,涵盖了众多最佳实践和设计模式。这里我们将...
1. **环境配置**:学习Java的第一步通常是安装Java Development Kit (JDK),设置好环境变量,包括`JAVA_HOME`, `PATH`, 和 `CLASSPATH`,确保系统能够识别并执行Java程序。 2. **基础语法**:掌握Java的基础语法是...
第 2 条:当面临许多构造函数参数时考虑构建器 伸缩构造函数模式有效,但是当参数很多时很难编写客户端代码,而且更难阅读 Builder 模式模拟命名的可选参数 Class.newInstance 破坏编译时异常检查 在设计具有构造...
#### 一、《Effective Java》第二版 - **书名及版本**:Effective Java(第二版) - **出版社**:Prentice Hall PTR - **作者**:Joshua Bloch - **作者背景**:Joshua Bloch曾在Sun Microsystems工作,是Java平台...
第二部分的学习资料可能涵盖多个主题,包括核心Java、J2EE框架、数据库交互、Web开发、面试准备等。以下是基于这些关键词可能包含的一些详细知识点: 1. **核心Java**: - Java语法基础:包括变量、数据类型、...
### Java学习路径(三)过程篇 #### 一、初识Java:安装与环境配置 在开始学习Java之前,最重要的是准备好开发环境。这通常包括安装JDK(Java Development Kit),这是开发Java程序的基础工具包。JDK包含了编译、...