0115_建造者模式(Builder)
建造者模式(Builder)
意图
将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
UML 图

优点
- 封装性好:建造者模式将复杂对象的构建过程封装在具体的建造者中,客户端无需知道内部细节
- 构建与表示分离:将对象的构建过程与表示分离,使得同样的构建过程可以创建不同的表示
- 易于扩展:增加新的具体建造者无需修改原有代码,符合"开闭原则"
- 更好的控制构建过程:可以更精细地控制复杂对象的构建步骤和顺序
缺点
- 产品需要有共同点:建造者模式所创建的产品一般具有较多的共同点,如果产品之间的差异性很大,则不适合使用建造者模式
- 增加了系统复杂度:如果产品的内部变化复杂,可能会导致需要定义很多具体建造者来实现这种变化
- 需要创建多个建造者:对于不同类型的产品,需要编写不同的建造者类,增加了系统的类数量
代码示例
以下是一个建造者模式示例,模拟构建不同类型的人类。正常人包含头、手臂、腿、身体,残疾人包含手臂、腿、身体会有一些缺陷。
1. 产品类 (Product)
//人类对象
public class Human {
// 头部属性
private String head;
// 手臂属性
private String arms;
// 腿部属性
private String legs;
// 身体属性
private String body;
/**
* 设置头部
* @param head 头部描述
*/
public void setHead(String head) {
this.head = head;
}
/**
* 设置手臂
* @param arms 手臂描述
*/
public void setArms(String arms) {
this.arms = arms;
}
/**
* 设置腿部
* @param legs 腿部描述
*/
public void setLegs(String legs) {
this.legs = legs;
}
/**
* 设置身体
* @param body 身体描述
*/
public void setBody(String body) {
this.body = body;
}
}
2. 抽象建造者 (Abstract Builder)
// 人类建造者接口
public interface Builder{
/**
* 构建头部
*/
void buildHead();
/**
* 构建身体
*/
void buildBody();
/**
* 构建腿部
*/
void buildLegs();
/**
* 构建手臂
*/
void buildArms();
Human build();
}
3. 具体建造者 (Concrete Builders)
// 正常人建造者
public class NormalHumanBuilder implements Builder{
private Human human;
public NormalHumanBuilder() {
human = new Human();
}
public void buildHead() {
human.setHead("建造头部 - 完整");
}
public void buildBody() {
human.setBody("建造身体 - 完整");
}
public void buildLegs() {
human.setLegs("建造腿部 - 完整");
}
public void buildArms() {
human.setArms("建造手臂 - 完整");
}
public Human build() {
return human;
}
}
// 残疾人建造者
public class DisabledHumanBuilder implements Builder {
private Human human;
public DisabledHumanBuilder() {
human = new Human();
}
@Override
public void buildHead() {
human.setHead("建造头部 - 完整");
}
@Override
public void buildBody() {
human.setBody("建造身体 - 有缺陷");
}
@Override
public void buildLegs() {
human.setLegs("建造腿部 - 残缺");
}
@Override
public void buildArms() {
human.setArms("建造手臂 - 残缺");
}
/**
* 构建并返回残疾人对象
* @return 构建完成的残疾人对象
*/
public Human build() {
return human;
}
}
4. 指挥者 (Director)
public class Director {
// 持有具体建造者的引用
private Builder builder;
/**
* 构造方法,注入具体建造者
* @param builder 具体的建造者实现
*/
public Director(Builder builder) {
this.builder = builder;
}
/**
* 创建人类对象的方法
* 按照头、身体、腿、手臂的顺序构建人类
* @return 构建完成的人类对象
*/
public Human createHuman() {
// 构建头部
builder.buildHead();
// 构建身体
builder.buildBody();
// 构建腿部
builder.buildLegs();
// 构建手臂
builder.buildArms();
// 返回构建完成的产品
return builder.build();
}
}
5. 客户端代码 (Client Code)
public static void main(String[] args) {
// 创建正常人类建造者
Builder normalBuilder = new NormalHumanBuilder();
// 创建残疾人建造者
Builder disabledBuilder = new DisabledHumanBuilder();
// 创建指导者并传入正常人类建造者
Director normalDirector = new Director(normalBuilder);
// 创建指导者并传入残疾人建造者
Director disabledDirector = new Director(disabledBuilder);
// 构建正常人类
Human normalHuman = normalDirector.createHuman();
System.out.println("正常人类构建完成");
// 构建残疾人
Human disabledHuman = disabledDirector.createHuman();
System.out.println("残疾人构建完成");
}
在Spring框架中的应用
建造者模式在Spring框架中有多种应用场景:
-
BeanDefinitionBuilder:用于构建BeanDefinition对象,提供了流畅的API来配置bean的各种属性
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(MyBean.class); builder.addPropertyValue("name", "testBean"); builder.setScope(BeanDefinition.SCOPE_SINGLETON); BeanDefinition beanDefinition = builder.getBeanDefinition(); -
MockMvcBuilders:在Spring测试框架中用于构建MockMvc实例
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) .addFilter(new CharacterEncodingFilter("UTF-8", true)) .build(); -
UriComponentsBuilder:用于构建URI组件
UriComponents uriComponents = UriComponentsBuilder .fromPath("/api/users") .queryParam("name", "John") .queryParam("age", 30) .build(); -
ResponseEntityBuilder:用于构建HTTP响应实体
ResponseEntity<String> response = ResponseEntity .status(HttpStatus.OK) .header("Content-Type", "application/json") .body("{\"message\": \"success\"}");
总结
建造者模式通过将复杂对象的构建过程分解为多个步骤,使得相同的构建过程可以创建不同的表示。它特别适用于那些具有复杂内部结构、需要多个步骤构建、且构建过程相对稳定的对象。在Spring框架中,建造者模式被广泛应用于各种配置和构建场景,提供了清晰、流畅的API来创建复杂对象。

浙公网安备 33010602011771号