定义:
建造者模式(Builder Pattern)是一种创建型设计模式,它用于构建复杂对象的表示。这种模式将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。建造者模式通常用于解决复杂对象的逐步构建问题。
建造者模式的关键特点包括:
- 分离复杂对象的构造和表示:
- 允许客户端不必了解内部组成的细节,就可以构造复杂的对象。通常用于创建具有多个部分的对象,特别是当这些部分需要通过多个步骤进行构建时。
- 提供控制复杂性的方法:
- 通过一个指导者(Director)和多个不同的建造者(Builder)实现,指导者负责按照特定步骤构建产品,而建造者提供这些步骤的具体实现。
- 流畅的接口风格:
- 建造者模式经常以链式调用(Fluent Interface)的形式实现,即每个设置方法都返回Builder对象本身,使得构建过程的步骤可以顺畅地链接在一起。
建造者模式通常涉及以下几个角色:
- 建造者(Builder):为创建一个产品对象的各个部件指定抽象接口。
- 具体建造者(Concrete Builder):实现Builder的接口以构造和装配该产品的各个部件。定义并明确它所创建的表示,并提供一个检索产品的接口。
- 指导者(Director):构造一个使用Builder接口的对象。
- 产品(Product):表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程。
这种模式在需要生成各种复杂对象时非常有用,特别是当这些对象的创建过程需要多个步骤时。通过独立控制过程和复杂对象的各个部分的构造,建造者模式提供了一种更灵活和可控的方式来创建复杂对象。
解决的问题:
- 处理复杂对象的构造:
- 当对象的构造过程非常复杂,包含多个组成部分和层次时,使用建造者模式可以逐步构建对象,而不是通过一个包含大量参数的复杂构造函数。
- 分离对象的构造和表示:
- 建造者模式提供了一种方法,将一个对象的构造过程与其表示分离开来,这样同样的构建过程可以创建不同的表示。
- 提高构造对象的可读性和易用性:
- 当创建一个对象需要很多步骤时,使用建造者模式可以使客户端代码更加清晰、易于理解和使用。
- 控制对象的构造过程:
- 建造者模式允许精细控制对象的构造过程。在构建过程中,可以更改产品的类型和内容。
- 可选参数的灵活处理:
- 在对象有多个可选参数时,使用建造者模式可以避免构造函数参数列表过长,以及处理多个参数组合的复杂性。
- 不变性的保证:
- 当对象一旦创建后就不应该改变其状态时,建造者模式可以在对象完全构建好后一次性地返回,从而保证对象的不变性。
使用场景:
- 复杂对象的构建:
- 当需要构建的对象很复杂,具有多个组件时,尤其是这些组件的构建顺序或组合方式可能变化。
- 构造参数多且复杂:
- 当对象的构造过程涉及多个参数时,特别是当有些参数是可选的,建造者模式提供了一种更清晰和安全的方式来构建对象。
- 不同表示的对象:
- 当需要创建多个不同表示的相同类型对象时,建造者模式允许使用相同的构建过程创建不同的表示。
- 需要封装构建过程:
- 当构建过程需要被封装起来,以便提供不同的表示,同时保持客户端与创建过程的解耦。
- 构建过程的步骤化:
- 当对象的创建需要多个步骤,且这些步骤需要按特定顺序执行时。建造者模式使得执行顺序的控制更加灵活。
- 不可变对象的创建:
- 对于需要创建不可变对象的场景,建造者模式可以先逐步构建对象的状态,然后一次性地返回最终对象,确保其不可变性。
示例代码:
// 产品类 - 计算机
public class Computer {
private String CPU;
private String memory;
private String storage;
private String screen;
private String operatingSystem;
private Computer(Builder builder) {
this.CPU = builder.CPU;
this.memory = builder.memory;
this.storage = builder.storage;
this.screen = builder.screen;
this.operatingSystem = builder.operatingSystem;
}
// getter方法
// 静态内部Builder类
public static class Builder {
private String CPU;
private String memory;
private String storage;
private String screen;
private String operatingSystem;
public Builder CPU(String CPU) {
this.CPU = CPU;
return this;
}
public Builder memory(String memory) {
this.memory = memory;
return this;
}
public Builder storage(String storage) {
this.storage = storage;
return this;
}
public Builder screen(String screen) {
this.screen = screen;
return this;
}
public Builder operatingSystem(String operatingSystem) {
this.operatingSystem = operatingSystem;
return this;
}
public Computer build() {
return new Computer(this);
}
}
}
// 使用建造者模式构建对象
public class BuilderPatternDemo {
public static void main(String[] args) {
Computer computer = new Computer.Builder()
.CPU("Intel Core i7")
.memory("16GB RAM")
.storage("512GB SSD")
.screen("15 inch 4K")
.operatingSystem("Windows 10")
.build();
// 使用computer对象
}
}
主要符合的设计原则:
- 单一职责原则(Single Responsibility Principle):
- 建造者模式通过将复杂对象的构造过程从其表示中分离出来,使得构造过程和表示方法有单一的职责。构造逻辑在建造者中实现,而对象的表示则在产品类中。
- 开闭原则(Open-Closed Principle):
- 建造者模式支持开闭原则,因为可以在不修改现有代码的情况下引入新的类型的建造者。如果需要创建一个新类型的对象,你只需要添加一个新的具体建造者类。
- 里氏替换原则(Liskov Substitution Principle):
- 尽管建造者模式不直接体现里氏替换原则,但它允许扩展建造者,新的建造者继承基本建造者时,可以替换基本建造者而不影响指导者的使用。
- 接口隔离原则(Interface Segregation Principle):
- 建造者模式通常使用接口来定义建造者的方法,这些接口仅暴露必要的方法,从而遵守接口隔离原则。
- 依赖倒转原则(Dependency Inversion Principle):
- 在建造者模式中,指导者类(Director)依赖于建造者接口(Builder),而不是具体的建造者实现类。这样做降低了指导者和具体建造者之间的耦合,符合依赖倒转原则。
综上所述,建造者模式通过上述原则的应用,提高了代码的模块化和灵活性,降低了各个类之间的耦合。
在JDK中的应用:
java.lang.StringBuilder
/java.lang.StringBuffer
:StringBuilder
和StringBuffer
类在构建字符串时采用了建造者模式。这些类提供了链式方法调用来逐步构建和修改字符串,最后通过toString()
方法返回最终的字符串对象。
java.nio.ByteBuffer
:- 在Java NIO中,
ByteBuffer
类及其兄弟类(如CharBuffer
,ShortBuffer
等)提供了一种类似建造者模式的方法来构建和操作缓冲区。例如,可以链式调用put()
方法向缓冲区添加数据。
- 在Java NIO中,
java.sql.PreparedStatement
:- 在JDBC API中,
PreparedStatement
类使用类似建造者模式的方法来逐步构建SQL语句。通过一系列的setXxx()
方法设置参数,最后执行查询或更新。
- 在JDBC API中,
- Java Stream API:
- 在Java 8及以上版本中,Stream API使用类似建造者模式的链式调用来构建和处理数据流。例如,可以通过一系列的中间操作(如
filter
,map
)构建数据流,最后通过终端操作(如collect
,forEach
)完成数据处理。
- 在Java 8及以上版本中,Stream API使用类似建造者模式的链式调用来构建和处理数据流。例如,可以通过一系列的中间操作(如
在Spring中的应用:
- Spring Security的配置:
- 在Spring Security中,安全配置通常通过一个流畅的接口实现,这允许通过链式方法调用来构建安全约束。例如,
.http().authorizeRequests().antMatchers("/admin").hasRole("ADMIN").and().formLogin()
这样的配置就是使用建造者模式来实现的。
- 在Spring Security中,安全配置通常通过一个流畅的接口实现,这允许通过链式方法调用来构建安全约束。例如,
- RestTemplate Builder:
- 在Spring提供的
RestTemplateBuilder
类中,建造者模式被用来构建RestTemplate
实例。这种方式允许客户端在构建RestTemplate
时灵活地添加定制化的功能,如消息转换器、请求工厂、拦截器等。
- 在Spring提供的
- Spring Boot的ApplicationBuilder:
- 在Spring Boot中,
SpringApplicationBuilder
类用于构建和配置SpringApplication
和ApplicationContext
。它提供了一种流畅的API来定制Spring应用的行为。
- 在Spring Boot中,
- Spring Framework的UriComponentsBuilder:
UriComponentsBuilder
是用于构建URI的工具类,提供了一种流畅的API来构建UriComponents
实例,这是建造者模式的典型应用。
在这些例子中,建造者模式允许通过一个简洁且易读的接口逐步构建复杂对象。它使得代码更加清晰,并且可以灵活地构建对象,而不必担心对象的构建过程中的细节。这种模式在需要构建配置复杂的对象时特别有用,如在配置安全性、创建REST客户端或构建复杂的URI时。