建造者用于构建复杂的对象,使用户可以在不知道对象的构建过程和细节的情况下就可以直接创建复杂的对象。
遇到多个构造器参数时要考虑使用建造者模式( builder模式 ),相比于重叠器模式和JavaBean模式,用Builder模式构建的对象更利于使用。
以下以Student的构建为例对比以下三种模式,其中Student 的 id 和 name 是必要参数,其它的为非必须参数。
1.重叠构造器模式
先写一个包含所有参数的构造函数,然后在其它构造函数中填写默认值去调用它。
/**
* 重叠构造器模式
*/
public class Student1 {
private int id;
private String name;
private int age;
private String sex;
private String address;
private String nickName;
public Student1(int id, String name, int age, String sex, String address, String nickName) {
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
this.address = address;
this.nickName = nickName;
}
public Student1(int id, String name, int age, String sex, String address) {
this(id, name, age, sex, address, "-");
}
public Student1(int id, String name, int age, String sex) {
this(id, name, age, sex, "-");
}
public Student1(int id, String name, int age) {
this(id, name, age, "未知");
}
public Student1(int id, String name) {
this(id, name, 0);
}
public String toString() {
return this.id + " " + this.name + " " + this.age + " " + this.sex + " " + this.address + " " + this.nickName;
}
}
一旦参数很多,这种写法会变得非常的复杂而且难以阅读,在生成对象的时候,有很多参数你根本就不想去设置它,但是又不得不设置,所以在构建复杂对象的时候不建议使用这种方法的。
2.JavaBean模式
提供一个只有必要参数的构造方法,然后通过set方法依次去指定其它非必须参数。
/**
* JavaBean模式
*/
public class Student2 {
private int id;
private String name;
private int age;
private String sex;
private String address;
private String nickName;
public Student2(){}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String toString() {
return this.id + " " + this.name + " " + this.age + " " + this.sex + " " + this.address + " " + this.nickName;
}
}
这种方法相对于重叠构造器模式有很大的改进,编写和使用都比较简单,也易于阅读,但是由于构造过程被分到了几个调用中,不是一次性完成的,在构造过程中JavaBean可能处于不一致的状态。
Student2 student2=new Student2(2,"宇智波佐助");
student2.setAge(16);
student2.setSex("男");
student2.setAddress("木叶忍者村忍者路18号");
student2.setNickName("屌爆你");
3.建造者模式
构建一个和外部类参数一致的静态内部类,内部类使用类似于JavaBean的构造方法,然后提供一个build方法生成外部类。
/**
* builder 模式
*/
public class Student3 {
//必要参数
private int id;
private String name;
//非必要参数
private int age;
private String sex;
private String address;
private String nickName;
public Student3(Builder builder) {
this.id = builder.id;
this.name = builder.name;
this.age = builder.age;
this.sex = builder.sex;
this.address = builder.address;
this.nickName = builder.nickName;
}
public static class Builder {
//必要参数
private int id;
private String name;
//非必要参数
private int age;
private String sex;
private String address;
private String nickName;
public Builder(int id, String name) {
this.id = id;
this.name = name;
}
public Builder age(int age) {
this.age = age;
return this;
}
public Builder sex(String sex) {
this.sex = sex;
return this;
}
public Builder address(String address) {
this.address = address;
return this;
}
public Builder nickName(String nickName) {
this.nickName = nickName;
return this;
}
public Student3 build() {
return new Student3(this);
}
}
public String toString() {
return this.id + " " + this.name + " " + this.age + " " + this.sex + " " + this.address + " " + this.nickName;
}
}
这种方式继承了JavaBean模式的优点,又使其构造过程一次性完成了,是对于JavaBean模式的一种改进,构造复杂对象时推荐使用这种模式。
三种构造方法的调用
public static void main(String args[]){
//1.重叠构造器模式
Student1 student1 =new Student1(1,"漩涡鸣人",15);
Student1 student11 =new Student1(1,"漩涡鸣人",15,"男","-","吊车尾");
//2.JavaBean模式
Student2 student2=new Student2(2,"宇智波佐助");
student2.setAge(16);
student2.setSex("男");
student2.setAddress("木叶忍者村忍者路18号");
student2.setNickName("屌爆你");
//3.Builder模式
Student3 student3=new Student3.Builder(3,"波风水门").age(25).address("天堂村").nickName("火影第一帅").build();
//打印输出
System.out.println("重叠构造器模式 student:"+student1.toString());
System.out.println("JavaBean模式 student:"+student2.toString());
System.out.println("builder模式 student:"+student3.toString());
}