建造者模式(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();}@Overridepublic void buildHead() {human.setHead("建造头部 - 完整");}@Overridepublic void buildBody() {human.setBody("建造身体 - 有缺陷");}@Overridepublic void buildLegs() {human.setLegs("建造腿部 - 残缺");}@Overridepublic 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来创建复杂对象。
