一、简介
建造者模式(Builder Pattern)是一种创建型设计模式,旨在通过将复杂对象的构建步骤拆分为多个单独的构建步骤来创建对象。它允许您按照步骤构建对象,以逐步添加不同的部件,最终组装成一个完整的对象。
该模式包含以下主要角色:
- 产品(Product): 表示正在构建的复杂对象。它包含多个部件,而具体构建步骤则在构建者对象中定义。
- 抽象构建者(Builder): 声明了构建产品各个部件的抽象接口。通常包括多个抽象方法,每个方法用于构建产品的一个部件。
- 具体构建者(Concrete Builder): 实现了抽象构建者接口,负责构建产品的各个部件。每个具体构建者对应一个特定的产品构建过程,定义了构建产品各个部件的具体步骤和顺序。
- 指挥者(Director): 负责按照特定顺序调用构建者接口中的方法,以构建最终的产品。指挥者知道构建的步骤和顺序,但不直接参与构建过程。
建造者模式的核心思想是将对象的构建过程和其最终表示分离开来,以便通过不同的构建者实现不同的构建过程,最终构建出不同形态的产品。这种模式适用于创建对象复杂、多步骤、多部分组成的情况,同时提供了更好的灵活性和控制性。
二、建造者模式
2.1、需求列表
变量 | 说明 | 是否必填 | 默认值 |
---|---|---|---|
taskName | 任务名称 | 是 | 无 |
minIdle | 最小线程数 | 否 | 1 |
maxIdle | 最大线程数 | 否 | 8 |
coreIdle | 核心线程数 | 否 | 2 |
如果出现某些参数是必填的,放在构造函数,可能参数列表会很长,容易传错值;如果使用setter方法,那么setter方法就会很复杂,甚至还有一些约束条件,那么配置项的校验逻辑就会很复杂。假设我们希望对象创建好后,不能再修改内部的值,就不能暴露setter方法了。所以建造者模式就能解决这写问题。
2.2、实现
TaskPoolConfig.java
public class TaskPoolConfig {
private String taskName;
private int minIdle;
private int maxIdle;
private int coreIdle;
private TaskPoolConfig(Builder builder) {
this.taskName = builder.taskName;
this.minIdle = builder.minIdle;
this.maxIdle = builder.maxIdle;
this.coreIdle = builder.coreIdle;
}
public static class Builder {
private static final int DEFAULT_MIN_IDLE = 1;
private static final int DEFAULT_MAX_IDLE = 8;
private static final int DEFAULT_CORE_IDLE = 2;
private String taskName;
private int minIdle = DEFAULT_MIN_IDLE;
private int maxIdle = DEFAULT_MAX_IDLE;
private int coreIdle = DEFAULT_CORE_IDLE;
public Builder setTaskName(String taskName) {
if (taskName == null || "".equals(taskName)) {
throw new IllegalArgumentException("任务名称不能为空");
}
this.taskName = taskName;
return this;
}
public Builder setMinIdle(int minIdle) {
if (minIdle <= 0) {
throw new IllegalArgumentException("最小线程数必须大于0");
}
this.minIdle = minIdle;
return this;
}
public Builder setMaxIdle(int maxIdle) {
if (maxIdle <= 0) {
throw new IllegalArgumentException("最大线程数必须大于0");
}
this.maxIdle = maxIdle;
return this;
}
public Builder setCoreIdle(int coreIdle) {
if (coreIdle <= 0) {
throw new IllegalArgumentException("核心线程数必须大于0");
}
this.coreIdle = coreIdle;
return this;
}
public TaskPoolConfig build() {
if (taskName == null || "".equals(taskName)) {
throw new IllegalArgumentException("任务名称不能为空");
}
if (minIdle > maxIdle) {
throw new IllegalArgumentException("最小线程数不能大于最大线程数");
}
if (coreIdle > maxIdle) {
throw new IllegalArgumentException("核心线程数不能大于最大线程数");
}
return new TaskPoolConfig(this);
}
}
public static void main(String[] args) {
TaskPoolConfig taskPoolConfig = new Builder().setTaskName("task_name")
.setMinIdle(2)
.setMaxIdle(20)
.setCoreIdle(10)
.build();
System.out.println(taskPoolConfig);
}
}
从上面可以看到TaskPoolConfig只能通过内部类生成(当然你也可以把Builder拎出去也是没问题的)。因为:
- TaskPoolConfig没有公开的构造方法
- TaskPoolConfig没有公开的setter方法
如果你构建时是这样:
public static void main(String[] args) {
// 核心线程数大于最大线程数会创建失败
TaskPoolConfig taskPoolConfig2 = new Builder().setTaskName("task_name")
.setMinIdle(2)
// .setMaxIdle(20)
.setCoreIdle(10)
.build();
System.out.println(taskPoolConfig2);
}
就会构建失败,因为核心线程数【10】大于最大线程数【默认值8】
三、优点与缺点
建造者模式是一种创建型设计模式,它允许您创建复杂对象的不同部分,并将它们组装成最终对象。优点和缺点如下所示:
优点:
- 分离构建和表示: 建造者模式允许您分离一个对象的构建过程和其最终表示。通过建造者模式,您可以更轻松地修改对象的内部表示。
- 更好的封装性: 您可以将对象构建过程的细节隐藏在其建造者之后,对外提供简单的接口,增强了对象的封装性。
- 更好的控制对象创建流程: 您可以控制对象的创建过程,逐步构建对象,灵活地添加不同的部件,以及根据需求灵活地配置对象。
- 创建复杂对象: 对于需要多个步骤、多个部分组装的复杂对象,建造者模式尤其有用,能够简化构建过程。
缺点:
- 增加代码量: 由于需要创建建造者类、指挥者类和产品类,可能会增加代码量,特别是在对象结构较为简单的情况下可能显得过于繁琐。
- 可能增加系统复杂性: 引入建造者模式后,系统中会增加额外的类和层级,可能会增加系统的复杂性。
- 不适用于对象结构简单的情况: 对于对象结构简单的情况下,使用建造者模式可能显得过于繁重,不够直接。
总的来说,建造者模式适用于需要创建复杂对象、具有多个部分组装、需要更好控制创建流程的情况。然而,在对象结构相对简单、创建过程较为直接的情况下,使用建造者模式可能会显得过于繁琐。