建造者模式
大约 8 分钟
建造者模式
什么是建造者模式
建造者模式(Builder Pattern)是一种创建型设计模式,它允许你分步骤创建复杂对象。该模式允许你使用相同的创建代码生成不同类型和形式的对象。
建造者模式的核心思想是:
- 将一个复杂对象的构建与其表示分离
- 使得同样的构建过程可以创建不同的表示
- 通过分步骤构建复杂对象,提高代码的可读性和可维护性
为什么需要建造者模式
在实际开发中,我们经常需要创建一些复杂的对象,这些对象通常包含多个组成部分,而且这些组成部分的创建过程可能比较复杂。如果直接在构造函数中创建这些对象,会导致构造函数参数过多,代码难以理解和维护。
建造者模式通过将复杂对象的构建过程分解为多个步骤,使得对象的创建过程更加清晰,同时也提供了更大的灵活性。
建造者模式的结构
建造者模式包含以下几个角色:
- 产品(Product):包含多个组成部件的复杂对象
- 抽象建造者(Builder):为创建一个产品对象的各个部件指定抽象接口
- 具体建造者(ConcreteBuilder):实现抽象建造者接口,构建和装配各个部件
- 指挥者(Director):构造一个使用建造者接口的对象,安排复杂对象的构建次序
建造者模式的实现
基本实现
// 产品类
class Product {
private String partA;
private String partB;
private String partC;
public void setPartA(String partA) {
this.partA = partA;
}
public void setPartB(String partB) {
this.partB = partB;
}
public void setPartC(String partC) {
this.partC = partC;
}
public void show() {
System.out.println("Product Parts:");
System.out.println("PartA: " + partA);
System.out.println("PartB: " + partB);
System.out.println("PartC: " + partC);
}
}
// 抽象建造者
abstract class Builder {
protected Product product = new Product();
public abstract void buildPartA();
public abstract void buildPartB();
public abstract void buildPartC();
public Product getResult() {
return product;
}
}
// 具体建造者
class ConcreteBuilder extends Builder {
@Override
public void buildPartA() {
product.setPartA("构建部件A");
}
@Override
public void buildPartB() {
product.setPartB("构建部件B");
}
@Override
public void buildPartC() {
product.setPartC("构建部件C");
}
}
// 指挥者
class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public Product construct() {
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
return builder.getResult();
}
}
// 使用示例
public class BuilderDemo {
public static void main(String[] args) {
Builder builder = new ConcreteBuilder();
Director director = new Director(builder);
Product product = director.construct();
product.show();
}
}
实际应用示例
// 计算机类
class Computer {
private String cpu;
private String ram;
private String storage;
private String graphicsCard;
private String motherboard;
public void setCpu(String cpu) {
this.cpu = cpu;
}
public void setRam(String ram) {
this.ram = ram;
}
public void setStorage(String storage) {
this.storage = storage;
}
public void setGraphicsCard(String graphicsCard) {
this.graphicsCard = graphicsCard;
}
public void setMotherboard(String motherboard) {
this.motherboard = motherboard;
}
public void showSpecs() {
System.out.println("=== 计算机配置 ===");
System.out.println("CPU: " + cpu);
System.out.println("内存: " + ram);
System.out.println("存储: " + storage);
System.out.println("显卡: " + graphicsCard);
System.out.println("主板: " + motherboard);
System.out.println("==================");
}
}
// 抽象计算机建造者
abstract class ComputerBuilder {
protected Computer computer = new Computer();
public abstract void buildCpu();
public abstract void buildRam();
public abstract void buildStorage();
public abstract void buildGraphicsCard();
public abstract void buildMotherboard();
public Computer getResult() {
return computer;
}
}
// 游戏电脑建造者
class GamingComputerBuilder extends ComputerBuilder {
@Override
public void buildCpu() {
computer.setCpu("Intel i9-12900K");
}
@Override
public void buildRam() {
computer.setRam("32GB DDR5");
}
@Override
public void buildStorage() {
computer.setStorage("2TB NVMe SSD");
}
@Override
public void buildGraphicsCard() {
computer.setGraphicsCard("NVIDIA RTX 4090");
}
@Override
public void buildMotherboard() {
computer.setMotherboard("ASUS ROG Maximus Z690");
}
}
// 办公电脑建造者
class OfficeComputerBuilder extends ComputerBuilder {
@Override
public void buildCpu() {
computer.setCpu("Intel i5-12400");
}
@Override
public void buildRam() {
computer.setRam("16GB DDR4");
}
@Override
public void buildStorage() {
computer.setStorage("512GB SSD");
}
@Override
public void buildGraphicsCard() {
computer.setGraphicsCard("集成显卡");
}
@Override
public void buildMotherboard() {
computer.setMotherboard("MSI B660M");
}
}
// 计算机建造指挥者
class ComputerDirector {
private ComputerBuilder builder;
public ComputerDirector(ComputerBuilder builder) {
this.builder = builder;
}
public Computer construct() {
builder.buildCpu();
builder.buildRam();
builder.buildStorage();
builder.buildGraphicsCard();
builder.buildMotherboard();
return builder.getResult();
}
// 构建高端游戏电脑
public Computer constructHighEndGamingPC() {
builder.buildCpu();
builder.buildRam();
builder.buildStorage();
builder.buildGraphicsCard();
builder.buildMotherboard();
return builder.getResult();
}
// 构建基础办公电脑
public Computer constructBasicOfficePC() {
builder.buildCpu();
builder.buildRam();
builder.buildStorage();
builder.buildMotherboard();
// 办公电脑不需要独立显卡
return builder.getResult();
}
}
// 使用示例
public class ComputerBuilderDemo {
public static void main(String[] args) {
// 构建游戏电脑
ComputerBuilder gamingBuilder = new GamingComputerBuilder();
ComputerDirector director = new ComputerDirector(gamingBuilder);
Computer gamingPC = director.constructHighEndGamingPC();
System.out.println("游戏电脑配置:");
gamingPC.showSpecs();
System.out.println();
// 构建办公电脑
ComputerBuilder officeBuilder = new OfficeComputerBuilder();
ComputerDirector director2 = new ComputerDirector(officeBuilder);
Computer officePC = director2.constructBasicOfficePC();
System.out.println("办公电脑配置:");
officePC.showSpecs();
}
}
建造者模式的应用场景
- 复杂对象的创建:当需要创建的对象具有复杂的内部结构时
- 对象创建过程独立于对象组成:当对象的创建过程需要独立于对象的组成部分以及它们的装配方式时
- 产品族的创建:当需要创建一系列相关或相互依赖的对象时
- 配置对象的创建:当需要创建具有多种配置的对象时
建造者模式的优缺点
优点
- 良好的封装性:客户端不需要知道产品内部组成的细节
- 建造者独立:具体的建造者类之间相互独立,便于扩展
- 便于控制细节风险:由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他模块产生任何影响
- 符合开闭原则:新增具体建造者无须修改原有类库,便于扩展
缺点
- 产品必须有共同点:建造者模式所创建的产品一般具有较多的共同点,其组成部分相似
- 建造者模式一般用在产品族的场景:如果产品之间的差异性很大,则不适合使用建造者模式
- 如果产品的内部变化复杂:可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大
建造者模式与其他创建型模式的比较
与工厂方法模式的区别
- 工厂方法模式:关注的是创建单个产品对象
- 建造者模式:关注的是创建复杂对象的各个部分,并最终组装成一个完整的产品
与抽象工厂模式的区别
- 抽象工厂模式:关注的是产品族的创建
- 建造者模式:关注的是产品部件的构建过程
建造者模式的变体
1. 流式建造者(Fluent Builder)
// 流式建造者模式
class FluentComputer {
private String cpu;
private String ram;
private String storage;
private String graphicsCard;
private String motherboard;
// 私有构造函数
private FluentComputer() {}
// 静态内部建造者类
public static class Builder {
private FluentComputer computer = new FluentComputer();
public Builder cpu(String cpu) {
computer.cpu = cpu;
return this;
}
public Builder ram(String ram) {
computer.ram = ram;
return this;
}
public Builder storage(String storage) {
computer.storage = storage;
return this;
}
public Builder graphicsCard(String graphicsCard) {
computer.graphicsCard = graphicsCard;
return this;
}
public Builder motherboard(String motherboard) {
computer.motherboard = motherboard;
return this;
}
public FluentComputer build() {
return computer;
}
}
public void showSpecs() {
System.out.println("=== 流式建造计算机配置 ===");
System.out.println("CPU: " + cpu);
System.out.println("内存: " + ram);
System.out.println("存储: " + storage);
System.out.println("显卡: " + graphicsCard);
System.out.println("主板: " + motherboard);
System.out.println("========================");
}
}
// 使用示例
public class FluentBuilderDemo {
public static void main(String[] args) {
FluentComputer computer = new FluentComputer.Builder()
.cpu("AMD Ryzen 9 5900X")
.ram("32GB DDR4")
.storage("1TB NVMe SSD")
.graphicsCard("AMD RX 6800 XT")
.motherboard("ASUS TUF Gaming X570-PLUS")
.build();
computer.showSpecs();
}
}
2. 带默认值的建造者
// 带默认值的建造者
class DefaultComputer {
private String cpu;
private String ram;
private String storage;
private String graphicsCard;
private String motherboard;
// 私有构造函数,接收建造者对象
private DefaultComputer(Builder builder) {
this.cpu = builder.cpu;
this.ram = builder.ram;
this.storage = builder.storage;
this.graphicsCard = builder.graphicsCard;
this.motherboard = builder.motherboard;
}
// 建造者类
public static class Builder {
// 设置默认值
private String cpu = "Intel i3-10100";
private String ram = "8GB DDR4";
private String storage = "256GB SSD";
private String graphicsCard = "集成显卡";
private String motherboard = "标准主板";
public Builder cpu(String cpu) {
this.cpu = cpu;
return this;
}
public Builder ram(String ram) {
this.ram = ram;
return this;
}
public Builder storage(String storage) {
this.storage = storage;
return this;
}
public Builder graphicsCard(String graphicsCard) {
this.graphicsCard = graphicsCard;
return this;
}
public Builder motherboard(String motherboard) {
this.motherboard = motherboard;
return this;
}
public DefaultComputer build() {
return new DefaultComputer(this);
}
}
public void showSpecs() {
System.out.println("=== 默认值计算机配置 ===");
System.out.println("CPU: " + cpu);
System.out.println("内存: " + ram);
System.out.println("存储: " + storage);
System.out.println("显卡: " + graphicsCard);
System.out.println("主板: " + motherboard);
System.out.println("======================");
}
}
// 使用示例
public class DefaultBuilderDemo {
public static void main(String[] args) {
// 只设置部分配置,其他使用默认值
DefaultComputer computer = new DefaultComputer.Builder()
.cpu("Intel i7-12700K")
.ram("16GB DDR4")
.build();
computer.showSpecs();
}
}
实际项目中的应用
// HTTP请求建造者示例
class HttpRequest {
private String url;
private String method;
private Map<String, String> headers;
private String body;
private int timeout;
// 私有构造函数
private HttpRequest(Builder builder) {
this.url = builder.url;
this.method = builder.method;
this.headers = builder.headers;
this.body = builder.body;
this.timeout = builder.timeout;
}
// 建造者类
public static class Builder {
private String url;
private String method = "GET";
private Map<String, String> headers = new HashMap<>();
private String body;
private int timeout = 5000; // 默认5秒超时
public Builder url(String url) {
this.url = url;
return this;
}
public Builder method(String method) {
this.method = method;
return this;
}
public Builder addHeader(String key, String value) {
this.headers.put(key, value);
return this;
}
public Builder body(String body) {
this.body = body;
return this;
}
public Builder timeout(int timeout) {
this.timeout = timeout;
return this;
}
public HttpRequest build() {
if (url == null || url.isEmpty()) {
throw new IllegalArgumentException("URL不能为空");
}
return new HttpRequest(this);
}
}
// Getter方法
public String getUrl() { return url; }
public String getMethod() { return method; }
public Map<String, String> getHeaders() { return headers; }
public String getBody() { return body; }
public int getTimeout() { return timeout; }
public void send() {
System.out.println("发送HTTP请求:");
System.out.println("URL: " + url);
System.out.println("Method: " + method);
System.out.println("Headers: " + headers);
System.out.println("Body: " + body);
System.out.println("Timeout: " + timeout + "ms");
}
}
// 使用示例
public class HttpRequestBuilderDemo {
public static void main(String[] args) {
// 构建GET请求
HttpRequest getRequest = new HttpRequest.Builder()
.url("https://api.example.com/users")
.addHeader("Authorization", "Bearer token123")
.timeout(3000)
.build();
getRequest.send();
System.out.println();
// 构建POST请求
HttpRequest postRequest = new HttpRequest.Builder()
.url("https://api.example.com/users")
.method("POST")
.addHeader("Content-Type", "application/json")
.body("{\"name\":\"张三\",\"age\":25}")
.timeout(10000)
.build();
postRequest.send();
}
}
总结
建造者模式是一种非常实用的创建型设计模式,它通过将复杂对象的构建过程与表示分离,使得同样的构建过程可以创建不同的表示。在实际开发中,当我们需要创建具有复杂内部结构的对象时,建造者模式是一个很好的选择。
使用建造者模式的关键点:
- 识别出需要创建的对象具有复杂的内部结构
- 将对象的构建过程分解为多个步骤
- 通过抽象建造者定义构建步骤的接口
- 通过具体建造者实现具体的构建逻辑
- 通过指挥者控制构建过程
建造者模式特别适用于以下场景:
- 创建复杂对象,其内部表示需要被独立构造
- 对象的创建过程需要被精细控制
- 需要创建具有多种配置的对象
- 希望提供清晰的API来构建对象
现代Java开发中,流式建造者模式(Fluent Builder)非常流行,它提供了链式调用的API,使代码更加简洁和易读。