使用静态工厂方法或者构造器有个共同的局限性:他们都不能很好的拓展到大量可选参数的情况。当有多个可选参数时,我们通常有两种方式来实例化相应的对象。
1.重叠构造器模式
public A(int a){}
public A(int a, int b){}
public A(int a, int b, int c){}
使用这种方式,通常需要在构造器中写入许多你并不想要的参数,但为了匹配构造器,又不得不写。总的来说,在可选参数太多时,使用重叠构造器使得客户端代码很难编写,并且可读性较差。
2.JavaBeans模式
这种模式下,调用无参构造器来产生一个对象,然后setter方法来设置所需的参数
public A(){}
public setter_a(int a){}
public setter_b(int b){}
public setter_c(int c){}
这种方式使代码可读性加强,但在多线程运行时可能会出现安全问题,导致代码错误调试起来非常困难。
3.Builder模式
既能保证安全性,也能保证代码的可读性。不直接生成想要的对象,而是会利用必须的元素调用构造器生成builder对象,然后客户端在builder对象上调用setter方法,来设置相关的可选参数。
public class A {
private int a;
private int b;
private int c;
public static class Builder {
private int a;
private int b;
private int c;
//假设a是必要的元素
public Builder(int a){this.a = a;}
//b,c是可选的元素
public Builder setb(int b) {
this.b = b;
return this
}
public Builder setc(int c) {
this.c = c;
return this
}
public A build() {
return new A(this)
}
}
private A(Builder builder) {
this.a = builder.a;
this.b = builder.b;
this.c = builder.c;
}
}
调用构造方法:
A instance=new A.Builder(a).setb(b).setc(c).build();
使用Builder解决了上述两种方式存在的一些问题,但是它本身也存在构造器复杂和创建对象开销大等问题。简而言之,类的构造器或静态工厂方法中有多个参数时,设计这种类,使用Builder模式是一个不错的,特别是在大多数参数可选的情况下。