1.遇到多个构造器参数时要考虑用构建器 注意是构建器不是构造器 说白了就是Builder设计模式。
- 无论是构造器(构造函数)还是静态工厂方法都有一个共同的局限性 那就是他们都很难扩展到大量的可选参数。
- 面对好多参数的时候我们可以用重叠构造器 (就是从第一个参数到最后一个参数的一次递增的创建构造器)。这样是可以解决问题但是很麻烦。
- 为了解决重叠构造器的麻烦冗长 我们引进了javabean模式就是创建一个无参的构造器 然后set get 属性。但是这种模式劣势就是构造的过程被分到几个调用中,在构造中可能处于不一致状态,无法保证一致性。多个线程 同时使用一个实例并且都在set的时候就可能乱了。出现不一致状态那个时候我们要额外的去确保他线程安全。
- javabeans 模式阻止了把类变成不可变的可能 什么是不可变的类(其实例不能被修改的类,每个实例包含的信息都必须在创建实例的时候提供,并在对象的整个生命周期内固定不变)
- build模式 既能保证像重叠构造器那样的安全,也能实现JavaBean模式那样的可读性。Builder模式可以将一个类的构建和表示进行分离。
- Builder模式:优点是可以将构造器的setter方法名取成类似注释的方式,这样我们可以很清晰的知道刚才究竟设置的什么值,可读性较高,缺点是比较冗长。
2.Builder模式的步骤:
- 不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器(或者静态工厂),得到一个build对象。
- 让客户端在build对象上调用类似的setter方法来设置每个相关的可选参数, 类似javaBeans模式。
- 最后,客户端调用无参的build方法来生成不可变的对象。这个builder是它构建的静态成员类。
package com.orbis.squery;
/**
* @author squery
* @date 2018/6/14
* @version v1.0.0
* @description
* @modified by
*/
public class Student {
private int id;
private String name;
private String passwd;
private String sex;
private String address;
// 构造器尽量缩小范围
private Student() {
}
// 构造器尽量缩小范围
private Student(Student origin) {
// 拷贝一份
this.id = origin.id;
this.name = origin.name;
this.passwd = origin.passwd;
this.sex = origin.sex;
this.address = origin.address;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public String getPasswd() {
return passwd;
}
public String getSex() {
return sex;
}
public String getAddress() {
return address;
}
/**
* Student的创建完全依靠Student.Builder,使用一种方法链的方式来创建
*
*/
public static class Builder {
private Student target;
public Builder() {
target = new Student();
}
public Builder address(int id) {
target.id = id;
return this;
}
public Builder name(String name) {
target.name = name;
return this;
}
public Builder password(String passwd) {
target.passwd = passwd;
return this;
}
public Builder sex(String sex) {
target.sex = sex;
return this;
}
public Builder address(String address) {
target.address = address;
return this;
}
public Student build() {
return new Student(target);
}
}
}
- Student并不是直接new出来的,对其构造器进行了处理使其可访问范围尽可能的小,只让它通过Student.Builder来构建自己,在Student.Builder中提供了一种类set的方法链的方式来设置值,然后在最后的build()方法的时候会返回一个Student对象,现在要创建一个Student对象,
Student s=new Student.Builder().name("CC").password("qwerty").sex("男")
.address("银河系第二旋臂").build();