建造者模式
模式概述
定义
建造者模式(Builder Pattern)是一种创建型设计模式,它将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示。

建造者模式要解决的问题
建造者模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象(包含多个成员变量的对象)。用户只需要制定复杂对象的类型就可以得到该对象,而无需知道其内部的具体的构造细节。
提示
想象你去一家餐厅点餐,服务员会问你:"需要什么口味?需要加辣吗?需要配饮料吗?"等一系列问题。这个过程就像建造者模式,通过一步步设置不同的选项,最终完成一份完整的订单。
为什么需要建造者模式?
假设我们需要创建一个资源池配置类:
public class ResourcePoolConfig {
private String name;
private int maxTotal;
private int maxIdle;
private int minIdle;
public ResourcePoolConfig(String name, Integer maxTotal, Integer maxIdle, Integer minIdle) {
if (StringUtils.isBlank(name)) {
throw new IllegalArgumentException("name should not be empty.");
}
this.name = name;
if (maxTotal != null) {
if (maxTotal <= 0) {
throw new IllegalArgumentException("maxTotal should be positive.");
}
this.maxTotal = maxTotal;
}
if (maxIdle != null) {
if (maxIdle < 0) {
throw new IllegalArgumentException("maxIdle should not be negative.");
}
this.maxIdle = maxIdle;
}
if (minIdle != null) {
if (minIdle < 0) {
throw new IllegalArgumentException("minIdle should not be negative.");
}
this.minIdle = minIdle;
}
}
}
这种实现方式有以下问题:
- 构造函数参数过多,容易出错。
- 参数之间可能有依赖关系,需要校验,破坏了不可变对象的封闭性。
- 代码可读性差,难以维护。
建造者模式实现
基本实现
public class ResourcePoolConfig {
private String name;
private int maxTotal;
private int maxIdle;
private int minIdle;
private ResourcePoolConfig(Builder builder) {
this.name = builder.name;
this.maxTotal = builder.maxTotal;
this.maxIdle = builder.maxIdle;
this.minIdle = builder.minIdle;
}
//建造者类
public static class Builder {
private static final int DEFAULT_MAX_TOTAL = 8;
private static final int DEFAULT_MAX_IDLE = 8;
private static final int DEFAULT_MIN_IDLE = 0;
private String name;
private int maxTotal = DEFAULT_MAX_TOTAL;
private int maxIdle = DEFAULT_MAX_IDLE;
private int minIdle = DEFAULT_MIN_IDLE;
public Builder setName(String name) {
if (StringUtils.isBlank(name)) {
throw new IllegalArgumentException("name should not be empty.");
}
this.name = name;
return this;
}
public Builder setMaxTotal(int maxTotal) {
if (maxTotal <= 0) {
throw new IllegalArgumentException("maxTotal should be positive.");
}
this.maxTotal = maxTotal;
return this;
}
public Builder setMaxIdle(int maxIdle) {
if (maxIdle < 0) {
throw new IllegalArgumentException("maxIdle should not be negative.");
}
this.maxIdle = maxIdle;
return this;
}
public Builder setMinIdle(int minIdle) {
if (minIdle < 0) {
throw new IllegalArgumentException("minIdle should not be negative.");
}
this.minIdle = minIdle;
return this;
}
public ResourcePoolConfig build() {
// 校验逻辑放到这里来做,包括必填项校验、依赖关系校验、约束条件校验等
if (StringUtils.isBlank(name)) {
throw new IllegalArgumentException("name should not be empty.");
}
if (maxIdle > maxTotal) {
throw new IllegalArgumentException("maxIdle cannot be greater than maxTotal.");
}
if (minIdle > maxTotal || minIdle > maxIdle) {
throw new IllegalArgumentException("minIdle cannot be greater than maxTotal or maxIdle.");
}
return new ResourcePoolConfig(this);
}
}
}
使用示例
// 使用建造者模式
ResourcePoolConfig config = new ResourcePoolConfig.Builder()
.setName("dbconnectionpool")
.setMaxTotal(16)
.setMaxIdle(10)
.setMinIdle(2)
.build();