引言
在软件开发中,有时需要构建具有复杂结构的对象,如果直接使用构造函数或者 setter 方法逐个设置对象的属性,会导致代码变得冗长、难以维护,并且容易出错。为了解决这个问题,我们可以使用建造者模式。
一、建造者模式概述
建造者模式是一种创建型设计模式,它的主要目的是将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。这种模式常用于构建具有复杂结构的对象,例如包含多个部件的对象,或者对象的构建过程需要进行多个步骤。
二、建造者模式的结构
建造者模式包含以下几个角色:
- 产品(Product):要构建的复杂对象,它由多个部件组成。
- 抽象建造者(Builder):定义了构建产品的抽象方法,具体建造者类将实现这些方法来构建具体的产品。
- 具体建造者(Concrete Builder):实现了抽象建造者定义的方法,负责构建产品的各个部件,并返回构建后的产品。
- 指挥者(Director):负责使用建造者构建产品的对象,它通常不了解具体的构建过程,只负责按照指定的步骤调用建造者的方法来构建产品。
三、建造者模式的优点
- 分步构建:将构建过程分步进行,每一步都由具体建造者负责,可以更加精细地控制构建过程。
- 隔离复杂性:将构建过程与产品的表示分离,使得构建过程的变化不会影响产品的表示,从而提高了系统的灵活性和可维护性。
- 复用性:可以使用相同的构建过程来构建不同的产品,提高了代码的复用性。
- 逐步完善:可以逐步完善构建过程,根据需求的变化灵活地调整构建过程。
四、建造者模式的应用场景
- 需要构建的产品具有复杂的内部结构,包含多个部件。
- 需要构建的产品的构建过程需要进行多个步骤,并且每个步骤的实现方式可能不同。
- 需要构建的产品的属性之间存在一定的约束关系,需要按照一定的顺序来构建产品。
五、建造者模式的示例代码
我们先来看下相关 UML 图
- 产品角色
java
package com.markus.desgin.mode.creational.builder;
/**
* @Author: zhangchenglong06
* @Date: 2024/3/7
* @Description:
*/
public class Car {
private Wheel wheel;
private SteeringWheel steeringWheel;
public Wheel getWheel() {
return wheel;
}
public void setWheel(Wheel wheel) {
this.wheel = wheel;
}
public SteeringWheel getSteeringWheel() {
return steeringWheel;
}
public void setSteeringWheel(SteeringWheel steeringWheel) {
this.steeringWheel = steeringWheel;
}
@Override
public String toString() {
return "Car{" +
"wheel=" + wheel +
", steeringWheel=" + steeringWheel +
'}';
}
}
package com.markus.desgin.mode.creational.builder;
/**
* @Author: zhangchenglong06
* @Date: 2024/3/7
* @Description:
*/
public interface SteeringWheel {
String steeringWheel();
}
package com.markus.desgin.mode.creational.builder;
/**
* @Author: zhangchenglong06
* @Date: 2024/3/7
* @Description:
*/
public class XiaomiSteeringWheel implements SteeringWheel {
@Override
public String steeringWheel() {
return "小米轮毂";
}
}
package com.markus.desgin.mode.creational.builder;
/**
* @Author: zhangchenglong06
* @Date: 2024/3/7
* @Description:
*/
public interface Wheel {
String wheelType();
}
package com.markus.desgin.mode.creational.builder;
/**
* @Author: zhangchenglong06
* @Date: 2024/3/7
* @Description:
*/
public class XiaomiWheel implements Wheel{
@Override
public String wheelType() {
return "小米方向盘";
}
}
- 抽象构建者
java
package com.markus.desgin.mode.creational.builder;
/**
* @Author: zhangchenglong06
* @Date: 2024/3/7
* @Description:
*/
public abstract class CarBuilder {
protected Car car = new Car();
public abstract CarBuilder buildWheel(Wheel wheel);
public abstract CarBuilder buildSteeringWheel(SteeringWheel steeringWheel);
public Car builder() {
return car;
}
}
- 具体构建者
java
package com.markus.desgin.mode.creational.builder;
/**
* @Author: zhangchenglong06
* @Date: 2024/3/7
* @Description:
*/
public class CommonCarBuilder extends CarBuilder {
@Override
public CarBuilder buildWheel(Wheel wheel) {
this.car.setWheel(wheel);
return this;
}
@Override
public CarBuilder buildSteeringWheel(SteeringWheel steeringWheel) {
this.car.setSteeringWheel(steeringWheel);
return this;
}
}
- 指挥官
java
package com.markus.desgin.mode.creational.builder;
/**
* @Author: zhangchenglong06
* @Date: 2024/3/7
* @Description:
*/
public interface Director<T> {
T construct();
}
package com.markus.desgin.mode.creational.builder;
/**
* @Author: zhangchenglong06
* @Date: 2024/3/7
* @Description: 小米制造商
*/
public class XiaoMiDirector implements Director<Car> {
private CarBuilder carBuilder;
public XiaoMiDirector(CarBuilder carBuilder) {
this.carBuilder = carBuilder;
}
@Override
public Car construct() {
carBuilder.buildWheel(new XiaomiWheel());
carBuilder.buildSteeringWheel(new XiaomiSteeringWheel());
return carBuilder.builder();
}
}
- 客户端
java
package com.markus.desgin.mode.creational.builder;
/**
* @Author: zhangchenglong06
* @Date: 2024/3/7
* @Description:
*/
public class Client {
public static void main(String[] args) {
CarBuilder carBuilder = new CommonCarBuilder();
Director<Car> director = new XiaoMiDirector(carBuilder);
Car car = director.construct();
System.out.println(car);
}
}
六、建造者模式在 Spring 中的应用
在Spring框架中,有几个组件使用了建造者模式的思想来构建复杂对象,其中包括:
- RestTemplateBuilder :
RestTemplateBuilder
是用于构建RestTemplate
实例的建造者。RestTemplate
是Spring提供的用于访问Restful服务的工具类,它支持各种HTTP请求方法和数据交换格式,如JSON和XML。RestTemplateBuilder
提供了一系列方法来配置RestTemplate
的各种属性,例如连接超时、读取超时、拦截器等,使得构建RestTemplate
实例更加灵活和便捷。 - WebMvcConfigurer :
WebMvcConfigurer
是Spring MVC框架中的一个接口,用于配置Web MVC的行为。在Spring Boot应用程序中,通常会创建一个实现了WebMvcConfigurer
接口的配置类来自定义Web MVC的行为。通过实现WebMvcConfigurer
接口,可以通过覆盖其中的方法来配置拦截器、消息转换器、视图解析器等各种组件,从而实现对Spring MVC框架的定制化。这种灵活性和可定制性正是建造者模式的优势之一。 - SqlSessionFactoryBean : 在Spring中使用MyBatis进行持久化操作时,通常会配置一个
SqlSessionFactoryBean
实例来创建SqlSessionFactory
对象。SqlSessionFactory
是MyBatis框架中的核心接口,用于创建SqlSession
对象,通过SqlSession
对象可以执行SQL语句并与数据库进行交互。SqlSessionFactoryBean
提供了一系列方法来配置MyBatis的各种属性,例如数据源、类型别名、Mapper扫描等,使得创建SqlSessionFactory
实例更加灵活和可配置。
这些组件在Spring框架中使用建造者模式的思想,通过提供一系列的配置方法来构建复杂的对象实例,使得对象的创建过程更加灵活和可定制。
七、设计模式百宝箱
在本节,我们开始填充我们的百宝箱:
- 面向对象基础
- 抽象
- 封装
- 多态
- 继承
- 面向对象原则
- 依赖抽象,不要依赖具体类
- 针对接口编程,不针对具体实现编程
- 类应该对扩展开放,对修改关闭
- 为交互对象之间的松耦合设计而努力
- 面向对象设计模式
- 简单工厂模式:定义了一个创建对象的接口,将创建对象的内容从客户端抽离出来
- 抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类
- 原型模式:通过复制现有对象来创建新对象,提高代码效率和可维护性
- 建造者模式:将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示
八、总结
建造者模式是一种创建型设计模式,通过将构建过程与产品的表示分离,使得同样的构建过程可以创建不同的表示。本文介绍了建造者模式的概念、结构、优点、应用场景,并提供了示例代码进行说明。建造者模式可以有效地解决构建复杂对象时的代码冗长、难以维护的问题,是一种值得推荐的设计模式。