1 如何创建有大量可选参数的类实例?
1.1 重叠构造器(telescoping constructor)模式
public class Student {
/*必填参数*/
private String name;
private int age;
/*可选参数*/
private String sex;
private String grade;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public Student(String name, int age, String sex, String grade) {
this.name = name;
this.age = age;
this.sex = sex;
this.grade = grade;
}
}
- 思考:如果只想创建包含name、age、grade参数的实例,怎么调用?sex参数就会冗余。
- 重叠构造器模式可行,但是当有许多参数的时候,客户端代码会很难编写,并且仍然较难以阅读。
1.2 JavaBean模式
先调用一个无参数构造器来创建对象,然后再调用setter方法来设置每个必要的参数,以及每个相关的可选参数。
public class Student {
/*必填参数*/
private String name;
private int age;
/*可选参数*/
private String sex;
private String grade;
public Student(){}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setSex(String sex) {
this.sex = sex;
}
public void setGrade(String grade) {
this.grade = grade;
}
}
- 优点:创建实例容易、可读性好
- 缺点:构造过程被分到几个调用中,在构造过程中,JavaBean可能处于不一致的状态,线程不安全;把类做成不可变的可能性不复存在
1.3 建造者(Builder)模式
不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器(或者静态工厂),得到一个builder对象,再调用类似setter的方法设置相关可选参数。
public class Student {
/*必填*/
private String name;
private int age;
/*选填*/
private String sex;
private String grade;
public static class Builder {
private String name;
private int age;
private String sex = "";
private String grade = "";
public Builder(String name, int age) {
this.name = name;
this.age = age;
}
public Builder sex(String sex) {
this.sex = sex;
return this;
}
public Builder grade(String grade) {
this.grade = grade;
return this;
}
public Student build() {
return new Student(this);
}
}
private Student(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.sex = builder.sex;
this.grade = builder.grade;
}
}
客户端代码:
Student student = new Student.Builder("jtzen9", 24).grade("1年级").build();
- 客户端代码很容易边写,并且便于阅读。Builder模式模拟了具名的可选参数。
- Builder模式还比重叠构造器模式更加冗长,因此只在有很多参数的时候才使用,比如4个或更多个参数。