设计模式之建造者模式

建造者模式(Builder Pattern)是一种创建型设计模式,旨在将一个复杂对象的构建过程与其表示分离。它允许通过一步步地构造对象,而不需要暴露对象的内部细节和构建过程。通常,这个模式适用于创建对象时需要多个步骤,而这些步骤是独立于对象类型的。

建造者模式的核心思想是:将复杂对象的创建过程分解成多个简单的步骤,并通过一个"建造者"来逐步构建这些步骤,从而得到最终的复杂对象。这个模式特别适合于需要动态创建不同类型的对象,且这些对象的构建过程可能涉及多个变化和不同的配置选项。

1. 建造者模式的结构

建造者模式通常由以下几个角色组成:

  1. Product(产品类):表示复杂对象的最终表示。建造者模式的目的是将这个复杂对象的创建过程封装起来,最终生成一个完整的产品。

  2. Builder(建造者):声明构建产品的抽象步骤,通常是一个接口或抽象类,定义了构建产品的各种部件的方法。

  3. ConcreteBuilder(具体建造者) :实现了 Builder 接口,完成具体的构建过程。每个具体建造者都负责一步步地构建一个产品实例,并且在最终返回产品时,会把各个部件组合成一个完整的对象。

  4. Director(指挥者) :负责指挥 Builder 的构建过程,按照特定的顺序调用 Builder 中的构建步骤。Director 类不参与产品的具体构建工作,它只关心构建的顺序和流程。

  5. Client(客户端) :通过 Director 来控制建造过程,最终得到复杂的产品对象。

2. 建造者模式的实现

2.1 例子:建造一个复杂的 Computer 对象

假设我们要创建一个 Computer 对象,该对象包含多个部件:处理器(CPU)、内存(RAM)、硬盘(Storage)等。每个部件的配置可以不同,并且它们的创建过程可能较为复杂。在这种情况下,建造者模式可以帮助我们一步步构建这个对象。

2.2 代码实现
  • 产品类
java 复制代码
public class Computer {
    private String CPU;
    private String RAM;
    private String Storage;

    public void setCPU(String CPU) {
        this.CPU = CPU;
    }

    public void setRAM(String RAM) {
        this.RAM = RAM;
    }

    public void setStorage(String Storage) {
        this.Storage = Storage;
    }

    @Override
    public String toString() {
        return "Computer [CPU=" + CPU + ", RAM=" + RAM + ", Storage=" + Storage + "]";
    }
}
  • 建造者接口
java 复制代码
public interface Builder {
    Computer computer = new Computer();
    void buildCPU();
    void buildRAM();
    void buildStorage();

    public Computer build();
}
  • 具体建造者类
java 复制代码
public class GamingComputerBuilder implements Builder{
     @Override
    public void buildCPU() {
        computer.setCPU("Intel i9");
    }

    @Override
    public void buildRAM() {
        computer.setRAM("32GB");
    }

    @Override
    public void buildStorage() {
        computer.setStorage("1TB SSD");
    }

    @Override
    public Computer build() {
        return computer;
    }
}
java 复制代码
public class OfficeComputerBuilder implements Builder{
    @Override
    public void buildCPU() {
        computer.setCPU("Intel i5");
    }

    @Override
    public void buildRAM() {
        computer.setRAM("8GB");
    }

    @Override
    public void buildStorage() {
        computer.setStorage("500GB HDD");
    }

    @Override
    public Computer build() {
        return computer;
    }
}
  • 指挥者类
java 复制代码
public class Director {
    private Builder builder;

    public Director(Builder builder){
        this.builder = builder;
    }

    public Computer construct(){
        builder.buildCPU();
        builder.buildRAM();
        builder.buildStorage();
        return builder.build();
    }
}
  • 测试程序
java 复制代码
public class Client {
    public static void main(String[] args) {
        //通过选择不同的构造器,实现不同产品的构筑
        // Director director = new Director(new GamingComputerBuilder());
        Director director = new Director(new OfficeComputerBuilder());

        Computer computer = director.construct();
        System.out.println(computer);
    }
}
2.3 运行结果
复制代码

在这个示例中:

  • Computer 类是复杂对象,它由多个部件(如 CPU、RAM、Storage)组成。
  • Builder 是构建 Computer 的抽象接口,定义了如何构建不同的部件。
  • GamingComputerBuilderOfficeComputerBuilderBuilder 接口的具体实现,负责创建不同配置的 Computer 对象。
  • Director 负责指挥构建过程,它会调用 Builder 中的方法按特定的顺序构建 Computer
  • 最终,客户端通过 Director 获取到构建好的 Computer 对象。

3. 建造者模式的优缺点

优点:
  1. 分离了复杂对象的构建与表示 :客户端只需要了解 DirectorBuilder,而不需要关心构建的细节。

  2. 灵活性高 :可以通过不同的 Builder 实现类,灵活地创建各种配置的对象,满足不同需求。

  3. 可读性强:每一步构建操作都明确地分开了,避免了将所有构建步骤堆叠在一起的情况,从而提高了代码的可读性和可维护性。

  4. 支持增量构建:每个建造者都可以支持增量构建,客户端可以控制每个构建步骤的细节,甚至动态调整对象的构建过程。

缺点:
  1. 类的数量增加 :为了实现建造者模式,通常会需要多个 Builder 类及 Director 类,这会导致类的数量增多,增加了系统的复杂度。

  2. 不适合所有情况:如果对象的构建非常简单,或者构建过程并不复杂,使用建造者模式可能显得过于复杂和冗余。

  3. 无法动态调整构建步骤:建造者模式通常在编译时就确定了构建的步骤顺序,因此它对动态调整和灵活变化的需求支持较差。

4. 应用场景

建造者模式适合以下场景:

  1. 对象构建过程复杂且有多个部分:例如,创建一个复杂的产品或对象,该对象由多个部件或配置组成。

  2. 需要构建不同表示的产品:当你需要构建不同的产品(例如,游戏电脑和办公电脑),这些产品具有相同的构建步骤,但部件的配置不同。

  3. 产品的构建过程独立于产品的具体类:如果你希望产品的构建过程与产品的具体类型分开,这时建造者模式非常适用。

5.建造者模式拓展

除了上述使用方式外,建造者模式在开发中还有一个常用的使用方式,就是当一个类构造器需要传入很多参数时,如果直接创建这个类的实例,代码可读性会非常差,而且很容易引入错误,此时就可以利用建造者模式进行重构。

手机类重构示例
  • 手机类
java 复制代码
package com.tian.pattern.builder.demo2;


public class Phone {

    private String cpu;
    private String screen;
    private String memory;
    private String mainboard;

    //私有构造方法
    private Phone(Builder builder) {
        this.cpu = builder.cpu;
        this.screen = builder.screen;
        this.memory = builder.memory;
        this.mainboard = builder.mainboard;
    }

    @Override
    public String toString() {
        return "Phone{" +
                "cpu='" + cpu + '\'' +
                ", screen='" + screen + '\'' +
                ", memory='" + memory + '\'' +
                ", mainboard='" + mainboard + '\'' +
                '}';
    }

    public static final class Builder {
        private String cpu;
        private String screen;
        private String memory;
        private String mainboard;

        public Builder cpu(String cpu) {
            this.cpu = cpu;
            return this;
        }

        public Builder screen(String screen) {
            this.screen = screen;
            return this;
        }
        public Builder memory(String memory) {
            this.memory = memory;
            return this;
        }
        public Builder mainboard(String mainboard) {
            this.mainboard = mainboard;
            return this;
        }

        //使用构建者创建Phone对象
        public Phone build() {
            return new Phone(this);
        }
    }
}
  • 测试类
java 复制代码
public class Client {
    public static void main(String[] args) {
        Phone phone = new Phone.Builder()
                .setCpu("intel")
                .setScreen("三星屏幕")
                .setMemory("金士顿内存条")
                .setMainboard("华硕主板")
                .build();

        System.out.println(phone);
    }
}
相关推荐
骄马之死3 小时前
SpringMVC + SpringBoot 核心知识点总结
java·spring boot·后端
zhengfei6113 小时前
第3章 Agent 类型分类与设计模式
设计模式
刀法如飞4 小时前
一文搞懂DDD 领域驱动设计思想原理
设计模式·架构·代码规范
郑洁文4 小时前
基于Spring Boot的流浪动物救助网站
java·spring boot·后端·毕设·流浪动物救助
螺丝钉code5 小时前
JAVA项目 Claude code CLAUDE.md 到底应该怎么写
java·人工智能·claude code
摇滚侠6 小时前
Maven 入门+高深 单一架构案例 54-59
java·架构·maven·intellij-idea
VidDown6 小时前
Webhook 调试器:让第三方回调“原形毕露”
java·开发语言·javascript·编辑器·postman
折哥的程序人生 · 物流技术专研6 小时前
Java 23 种设计模式:从踩坑到精通 | 原型模式 —— 克隆对象,深拷贝与浅拷贝的坑你踩过吗?
java·设计模式·架构·原型模式·单一职责原则
装不满的克莱因瓶7 小时前
基于 OpenResty 扩展开发实现动态服务注册与发现能力
java·开发语言·架构·openresty