文章目录
一、建造者模式
1.1 建造者模式的定义
建造者模式(Builder Pattern)也叫做生成器模式,其定义如下:
Separate the construction of a complex object from its representation so that the same construction process can create different representations.(将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。)
构建和表示的含义如下:
构建: 创建对象的过程,涉及按照一定的步骤、顺序来组合对象的各个部分,最终生成一个完整的对象。例如,构造一辆汽车包括安装发动机、安装轮胎、装配车身等步骤。论汽车的类型如何,这些基本步骤都是相同的。
表示:构建对象的具体形态或形式。不同的表示意味着通过同样的构建步骤,可以生成不同的对象形式。例如,汽车可以有不同的表示,比如一辆跑车和一辆卡车。尽管构建的过程都包括安装发动机、轮胎和车身等步骤,但不同的表示会在每个步骤中有所不同,比如跑车使用的是高性能发动机,而卡车可能使用的是大功率发动机。
同样的构建步骤所生成的对象的具体形式,可能会因构造器的不同而有所变化。
1.2 建造者模式的参与者
在建造者模式中,不同参与者的作用如下:
- Product(产品): 复杂对象的类,表示需要创建的复杂对象, 通常包含多个部件(字段)。它是建造者模式的最终生成目标。
- Builder(抽象建造者):定义了构建
Product
各部分的抽象接口。该接口规定了用于创建产品各个部件的方法,但并不实现这些方法。还包含一个返回最终产品对象的方法。 - ConcreteBuilder(具体建造者):具体化了创建产品各个部件的方法,负责跟踪构建过程的状态,并最终生成产品。每个具体建造者可以创建产品的不同表示。
- Director(指挥者):指挥者类负责控制构建过程的顺序,指导
Builder
来创建产品。换句话说,它定义了构建产品的步骤顺序,确保每个步骤按特定的顺序执行。
注意,Director 和 Builder 是聚合关系, 共同协作来完成对象的创建。
1.3 建造者模式的优点
- 封装性。不关注每一个具体的模型内部如何实现。
- 便于控制细节风险。由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。
1.4 建造者模式的使用场景
- 相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式。
- 如果类的属性之间有一定的依赖关系或者约束条件(源自设计模式之美),那么就可以考虑使用 Builder 设计模式。
- 产品类非常复杂,这个时候使用建造者模式非常合适。
二、普通案例
2.1 代码设计
具体工作流程为:
-
构建:我们定义一个构造器(
Builder
)类,用来逐步创建复杂对象。这个类包含生成对象的多个步骤(如“安装发动机”、“安装轮胎”)。 -
表示:我们定义不同的具体构造器(
ConcreteBuilder
)类,每个构造器生成一个特定的表示(如“跑车”或“卡车”)。
2.2 实现代码
本案例的实现代码位于 java-demos/builder-pattern at main · idealzouhu/java-demos (github.com)
三、Lombok 实现案例
Lombok 库中的注解 @Builder
可以自动创建一个实现建造者模式的类。当在类上添加@Builder注解后,Lombok会自动生成一个建造者类,可以在类的外部使用建造者模式来创建该类的实例。
实际上,仅使用建造者模式创建复杂对象时,我们有时候可能并不需要创建 Director 类, 而是在创建对象的时候手动指定产品创建步骤。
3.1 @Builder 使用方法
创建一个类,使用相应注解
@Data
@Builder
public class User {
// 用户 ID
private String userId;
// 用户名
private String username;
}
public class BuilderPatternExample {
public static void main(String[] args) {
User user = User.builder()
.userId("123456")
.username("zhangsan")
.build();
System.out.println(user); // 返回结果为 User(userId=123456, username=zhangsan)
}
}
3.2 @Builder 实际所作工作
查看编译后的 User 类的源码, 可以发现在内部创建了具体建造者 UserBuilder
public class User {
private String userId;
private String username;
@Generated
public static UserBuilder builder() {
return new UserBuilder();
}
// setter,getter,equal,construct,hashCode, toString等方法
...
@Generated
public static class UserBuilder {
@Generated
private String userId;
@Generated
private String username;
@Generated
UserBuilder() {
}
@Generated
public UserBuilder userId(final String userId) {
this.userId = userId;
return this;
}
@Generated
public UserBuilder username(final String username) {
this.username = username;
return this;
}
@Generated
public User build() {
return new User(this.userId, this.username);
}
}
}
参考资料
《设计模式之禅 (第2版)》