建造者模式
Builder模式,建造者模式、构建者模式或者生成器模式。
为什么需要建造者模式?
- 有了构造方法,为什么还需要建造者模式
- 有了set器,为什么还需要建造者模式
- 通过使用建造者模式可以避免在用Set器时引起创建对象的无效状态
- 建造者模式和工厂模式都能创建对象,二者的区别是什么
建造者模式的适用场景
- 我们把类的必填属性放到构造函数中,强制创建对象的时候就设置,某些属性字段的必填校验,如果通过构造函数传入,可以校验,但是会造成构造函数参数列表太长的问题(参数的顺序,参数的值就很关键),导致代码可读性变差,如果用Set器方式的话,不能保证创建对象时是否调用Set器
- 如果类的属性之间有依赖关系或者约束条件,如果用构造函数方法创建对象,则函数参数列表过多,如果使用Set器的话,无法满足某些对象属性之间的约束条件问题
- 如果我们需要创建不可变的对象(对象修改好后不希望提供修改点),不希望对外暴露Set接口时
建造者模式是如何实现的
我们可以先创建建造者对象,把校验逻辑放到Builder类中,并且通过Set器设置Builder对象属性值,然后在调用build()方法前集中做各种约束校验,校验通过之后才会创建对象
代码举例
public class ThreadPool {
/**
* 名称
*/
private String name;
/**
* 最大线程个数
*/
private int maxTotal;
/**
* 最大空闲个数
*/
private int maxIdle;
public ThreadPool(Builder builder) {
this.name = builder.name;
this.maxTotal = builder.maxTotal;
this.maxIdle = builder.maxIdle;
}
public static class Builder {
private String name;
private int maxTotal = 8;
private int maxIdle = 1;
public Builder name(String name) {
if (StringUtils.isEmpty(name)) {
throw new IllegalArgumentException("name is empty!");
}
this.name = name;
return this;
}
public Builder maxTotal(int maxTotal) {
if (maxTotal < 0 || maxTotal > 1024) {
throw new IllegalArgumentException("illegal maxTotal value !");
}
this.maxTotal = maxTotal;
return this;
}
public Builder maxIdle(int maxIdle) {
if (maxIdle < 0 || maxIdle > 1024) {
throw new IllegalArgumentException("illegal maxTotal value !");
}
this.maxIdle = maxIdle;
return this;
}
public ThreadPool build() {
// 属性之间的约束性校验
if (maxIdle > maxTotal) {
throw new IllegalArgumentException("illegal maxTotal value !");
}
return new ThreadPool(this);
}
}
public static void main(String[] args) {
ThreadPool threadPool = new ThreadPool.Builder()
.name("MyThreadPool")
.maxTotal(10)
.maxIdle(1)
.build();
}
}
建造者模式与工厂模式的区别
- 建造者模式是负责某一类型的复杂对象的创建工作
- 工厂模式负责创建不同但是相关类型的对象(继承同一类或者继承同一接口的子类),由给定参数来决定创建那种类型的对象