文章目录
- 概念
- 相关图示
- 代码示例
- 框架中的应用
- 场景
-
- 多个生成器(Concrete Builder):
- 单个生成器
概念
生成器设计模式(Builder Design Pattern)是一种创建型设计模式,用于处理具有多个属性和复杂构造过程的对象。生成器模式通过将对象的构建过程与其表示分离,使得相同的构建过程可以创建不同的表示。这有助于减少构造函数的参数个数,提高代码的可读性和可维护性。
生成器模式的核心组件包括:
- 产品(Product):需要创建的复杂对象。
- 抽象生成器(Builder):定义用于创建产品对象各个部分的接口。
- 具体生成器(Concrete Builder):实现抽象生成器接口,负责创建和组装产品的各个部分。
- 指挥者(Director):负责构建产品的过程,通常接受一个生成器对象作为参数,并使用该对象的方法来组装产品。
相关图示
图片来自:https://refactoringguru.cn/design-patterns/builder
代码示例
// 产品
class House {
private String foundation;
private String structure;
private String roof;
public void setFoundation(String foundation) {
this.foundation = foundation;
}
public void setStructure(String structure) {
this.structure = structure;
}
public void setRoof(String roof) {
this.roof = roof;
}
public String toString() {
return "Foundation: " + foundation + ", Structure: " + structure + ", Roof: " + roof;
}
}
// 抽象生成器
interface HouseBuilder {
void buildFoundation();
void buildStructure();
void buildRoof();
House getHouse();
}
// 具体生成器
class ConcreteHouseBuilder implements HouseBuilder {
private House house;
public ConcreteHouseBuilder() {
house = new House();
}
@Override
public void buildFoundation() {
house.setFoundation("Concrete Foundation");
}
@Override
public void buildStructure() {
house.setStructure("Concrete Structure");
}
@Override
public void buildRoof() {
house.setRoof("Concrete Roof");
}
@Override
public House getHouse() {
return house;
}
}
// 指挥者
class HouseDirector {
public House constructHouse(HouseBuilder builder) {
builder.buildFoundation();
builder.buildStructure();
builder.buildRoof();
return builder.getHouse();
}
}
// 客户端
public class BuilderPatternDemo {
public static void main(String[] args) {
HouseBuilder builder = new ConcreteHouseBuilder();
HouseDirector director = new HouseDirector();
House house = director.constructHouse(builder);
System.out.println(house);
}
}
框架中的应用
Spring Boot中的生成器设计模式的一个很好的例子是org.springframework.boot.web.client.RestTemplateBuilder
。这个生成器类可以帮助创建和配置RestTemplate
实例。使用RestTemplateBuilder
可以简化和优化RestTemplate
的创建过程,尤其是当有多个配置选项时。
public class RestTemplateBuilder {
//下面展示部分相关代码
private Duration connectTimeout;
private Duration readTimeout;
private ClientHttpRequestFactory requestFactory;
public RestTemplateBuilder() {
}
public RestTemplateBuilder connectTimeout(Duration connectTimeout) {
this.connectTimeout = connectTimeout;
return this;
}
public RestTemplateBuilder readTimeout(Duration readTimeout) {
this.readTimeout = readTimeout;
return this;
}
public RestTemplateBuilder requestFactory(ClientHttpRequestFactory requestFactory) {
this.requestFactory = requestFactory;
return this;
}
public RestTemplate build() {
SimpleClientHttpRequestFactory requestFactory = this.requestFactory == null ? new SimpleClientHttpRequestFactory() : (SimpleClientHttpRequestFactory) this.requestFactory;
if (this.connectTimeout != null) {
requestFactory.setConnectTimeout((int) this.connectTimeout.toMillis());
}
if (this.readTimeout != null) {
requestFactory.setReadTimeout((int) this.readTimeout.toMillis());
}
return new RestTemplate(requestFactory);
}
}
场景
生成器设计模式在不同场景下可能有不同的应用方式。以下是两种典型的场景
多个生成器(Concrete Builder):
当需要为同一产品(Product)提供不同的表示形式或构建过程时,可以使用多个生成器。每个生成器负责创建并组装产品的各个部分,但可能采用不同的配置、数据源或构建方法。
例如,假设有一个Report类,它需要根据不同的数据源(如CSV文件、数据库等)以及不同的格式(如HTML、PDF等)生成报告。在这种情况下,可以创建多个生成器,每个生成器负责从特定的数据源中读取数据并生成特定格式的报告。
interface ReportBuilder {
void loadDataSource();
void buildHeader();
void buildContent();
void buildFooter();
Report getReport();
}
class CSVToHtmlReportBuilder implements ReportBuilder {
// ...实现里面对应的方法
}
class DatabaseToPdfReportBuilder implements ReportBuilder {
// ...实现里面对应的方法
}
单个生成器
当一个复杂对象的变化仅仅是属性值的变化,而不涉及到整体结构的变化时,只需要一个生成者。在这种情况下,生成者可以通过扩展属性和填充属性的方法来创建具有不同属性值的复杂对象。
例如,假设我们正在构建一个汽车制造系统,系统可以生产不同颜色、轮胎类型和发动机类型的汽车。在这种情况下,我们可以使用一个汽车生成者,并通过提供不同的颜色、轮胎类型和发动机类型来创建具有不同属性的汽车。
public class Car {
private String color;
private String tireType;
private String engineType;
public void setColor(String color) {
this.color = color;
}
public void setTireType(String tireType) {
this.tireType = tireType;
}
public void setEngineType(String engineType) {
this.engineType = engineType;
}
@Override
public String toString() {
return "Car{" +
"color='" + color + ''' +
", tireType='" + tireType + ''' +
", engineType='" + engineType + ''' +
'}';
}
}
public class CarBuilder {
private Car car;
public CarBuilder() {
car = new Car();
}
public CarBuilder setColor(String color) {
car.setColor(color);
return this;
}
public CarBuilder setTireType(String tireType) {
car.setTireType(tireType);
return this;
}
public CarBuilder setEngineType(String engineType) {
car.setEngineType(engineType);
return this;
}
public Car build() {
return car;
}
}
public class Main {
public static void main(String[] args) {
CarBuilder carBuilder = new CarBuilder();
Car sportsCar = carBuilder.setColor("Red")
.setTireType("Sports")
.setEngineType("V8")
.build();
Car familyCar = carBuilder.setColor("Blue")
.setTireType("Standard")
.setEngineType("V6")
.build();
System.out.println(sportsCar);
System.out.println(familyCar);
}
}
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net