重叠构造器模式
可行(该模式构建对象时非常常见,参数较少时,使用方便,但可选的参数多起来后,构造器相互调用非常麻烦),但是有很多可选参数时,构造器的个数会很多,使得代码难以阅读。静态工厂和构造器有个共同的局限性:它们都不能很好地扩展到大量的可选参数。遇到许多构造器参数的时候,还有第二种代替方法,即JavaBeans模式
,在这种模式下,调用一个无参构造器来创建对象,然后调用setter方法来设置每个必要的参数,以及每个相关的可选参数。遗憾的是,JavaBeans模式自身有着很严重的缺点。因为构造过程被分到了几个调用中,在构造过程中JavaBean可能处于不一致的状态。与此相关的另一点不足在于,JavaBeans模式阻止了把类做成不可变的可能,这就需要程序员付出额外的努力来确保它的线程安全。第三种替代方案:builder模式
,既保证像重叠构造模式那样的安全性
,也能保证JavaBean 模式的可读性
。
以下为实际工程中的例子:这么构建User 对象
、
创建步骤:
- 客户端(例如上面代码中的Main方法)利用必要的参数调用
Builder类的构造器
得到一个builder对象 - 然后客户端在builder对象上调用类似于
setter方法
,来设置每个相关的可选参数 - 最后客户端调用无参数的
build方法
生产不可变对象。这个builder是他构建的类的静态成员类
//Mybatis 源码
public final class Environment {
private final String id;
private final TransactionFactory transactionFactory;
private final DataSource dataSource;
public Environment(String id, TransactionFactory transactionFactory, DataSource dataSource) {
if (id == null) {
throw new IllegalArgumentException("Parameter 'id' must not be null");
}
if (transactionFactory == null) {
throw new IllegalArgumentException("Parameter 'transactionFactory' must not be null");
}
this.id = id;
if (dataSource == null) {
throw new IllegalArgumentException("Parameter 'dataSource' must not be null");
}
this.transactionFactory = transactionFactory;
this.dataSource = dataSource;
}
//静态内部类:建造者模式
public static class Builder {
private String id;
private TransactionFactory transactionFactory;
private DataSource dataSource;
public Builder(String id) {
this.id = id;//Builder 构造器初始化必要参数
}
public Builder transactionFactory(TransactionFactory transactionFactory) {//赋值可选参数
this.transactionFactory = transactionFactory;
return this;
}
//赋值可选参数
public Builder dataSource(DataSource dataSource) {
this.dataSource = dataSource;
return this;
}
//无参数build方法
public Environment build() {
return new Environment(this.id, this.transactionFactory, this.dataSource);
}
}
//=====get和set方法==================
}