【设计模式】【创建型模式】建造者模式(Builder)

简介: 一、入门 什么是建造者模式? 建造者模式(Builder Pattern)是一种创建型设计模式,用于逐步构建复杂对象。 它通过将对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。 为什么

👋hi,我不是一名外包公司的员工,也不会偷吃茶水间的零食,我的梦想是能写高端CRUD

🔥 2025本人正在沉淀中... 博客更新速度++

👍 欢迎点赞、收藏、关注,跟上我的更新节奏

🎵 当你的天空突然下了大雨,那是我在为你炸乌云

一、入门

什么是建造者模式?

建造者模式(Builder Pattern)是一种创建型设计模式,用于逐步构建复杂对象。
它通过将对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。

为什么要建造者模式?

假设我们要组装电脑,需要cpu、内存、硬盘、gpu、电源...
没有使用建造者模式,我们会这样写:

public class Computer {
   
    private String cpu;
    private String memory;
    private String hardDisk;
    private String gpu;
    private String powerSupply;

    public Computer(String cpu, String memory, String hardDisk, String gpu, String powerSupply) {
   
        this.cpu = cpu;
        this.memory = memory;
        this.hardDisk = hardDisk;
        this.gpu = gpu;
        this.powerSupply = powerSupply;
    }
}

存在问题

  1. 构造方法参数过多(Telescoping Constructor Problem):调用这样的构造方法时,代码会变得非常冗长且难以理解:
Computer computer = new Computer("Intel i7", "16GB", "1TB SSD", "NVIDIA RTX 3080", "750W");
  1. 对象的不一致性:在某些情况下,对象可能需要在不同的步骤中逐步构建。如果没有建造者模式,对象可能会在未完全初始化的情况下被使用,导致不一致的状态。
  2. 代码的可读性可维护性变差:当对象的构建过程复杂时,直接在客户端代码中编写构建逻辑会导致代码重复和难以维护。
Computer computer = new Computer();
computer.setCpu("Intel i7");
computer.setMemory("16GB");
computer.setHardDisk("1TB SSD");
computer.setGpu("NVIDIA RTX 3080");
computer.setPowerSupply("750W");
  1. 缺乏灵活性:如果对象的构建过程需要支持多种不同的配置或表示形式,直接在客户端代码中编写构建逻辑会导致代码的灵活性降低。例如,如果需要构建不同类型的计算机(如游戏计算机、办公计算机等),每种类型的构建逻辑可能会有所不同,导致代码重复和难以扩展。

如何实现建造者模式?

传统建造者

主要角色

  1. Product(产品类):最终要构建的复杂对象。
  2. Builder(抽象建造者):定义构建步骤的接口。
  3. ConcreteBuilder(具体建造者):实现Builder接口,提供具体的构建步骤。
  4. Director(指挥者):负责调用Builder的步骤,控制构建过程。

【案例】组装电脑 - 改

image.png

Product(产品类)Computer类,最终要构建的复杂对象。

class Computer {
   
    private String cpu;
    private String memory;
    private String hardDisk;

    public void setCpu(String cpu) {
   
        this.cpu = cpu;
    }

    public void setMemory(String memory) {
   
        this.memory = memory;
    }

    public void setHardDisk(String hardDisk) {
   
        this.hardDisk = hardDisk;
    }

    @Override
    public String toString() {
   
        return "Computer [cpu=" + cpu + ", memory=" + memory + ", hardDisk=" + hardDisk + "]";
    }
}

Builder(抽象建造者)ComputerBuilder接口,定义构建步骤的接口。

interface ComputerBuilder {
   
    void buildCpu();
    void buildMemory();
    void buildHardDisk();
    Computer getComputer();
}

ConcreteBuilder(具体建造者)GamingComputerBuilder类,实现Builder接口,提供具体的构建步骤。

class GamingComputerBuilder implements ComputerBuilder {
   
    private Computer computer;

    public GamingComputerBuilder() {
   
        this.computer = new Computer();
    }

    @Override
    public void buildCpu() {
   
        computer.setCpu("Intel i7");
    }

    @Override
    public void buildMemory() {
   
        computer.setMemory("16GB");
    }

    @Override
    public void buildHardDisk() {
   
        computer.setHardDisk("1TB SSD");
    }

    @Override
    public Computer getComputer() {
   
        return computer;
    }
}

Director(指挥者)ComputerDirector类,负责调用Builder的步骤,控制构建过程。

class ComputerDirector {
   
    private ComputerBuilder computerBuilder;

    public ComputerDirector(ComputerBuilder computerBuilder) {
   
        this.computerBuilder = computerBuilder;
    }

    public void constructComputer() {
   
        computerBuilder.buildCpu();
        computerBuilder.buildMemory();
        computerBuilder.buildHardDisk();
    }

    public Computer getComputer() {
   
        return computerBuilder.getComputer();
    }
}

客户端代码

public class BuilderPatternDemo {
   
    public static void main(String[] args) {
   
        ComputerBuilder builder = new GamingComputerBuilder();
        ComputerDirector director = new ComputerDirector(builder);
        director.constructComputer();
        Computer computer = director.getComputer();
        System.out.println(computer);
    }
}

链式建造者

流式接口(Fluent Interface)或链式建造者模式。这种方式通过返回this来实现链式调用,代码更加简洁和直观。
下面是一个使用链式调用的建造者模式示例:

产品类(Computer)

class Computer {
   
    private String cpu;
    private String memory;
    private String hardDisk;
    private String gpu;

    public void setCpu(String cpu) {
   
        this.cpu = cpu;
    }

    public void setMemory(String memory) {
   
        this.memory = memory;
    }

    public void setHardDisk(String hardDisk) {
   
        this.hardDisk = hardDisk;
    }

    public void setGpu(String gpu) {
   
        this.gpu = gpu;
    }

    @Override
    public String toString() {
   
        return "Computer [cpu=" + cpu + ", memory=" + memory + ", hardDisk=" + hardDisk + ", gpu=" + gpu + "]";
    }
}

建造者类(ComputerBuilder)

class ComputerBuilder {
   
    private Computer computer;

    public ComputerBuilder() {
   
        this.computer = new Computer();
    }

    public ComputerBuilder buildCpu(String cpu) {
   
        computer.setCpu(cpu);
        return this; // 返回this,支持链式调用
    }

    public ComputerBuilder buildMemory(String memory) {
   
        computer.setMemory(memory);
        return this; // 返回this,支持链式调用
    }

    public ComputerBuilder buildHardDisk(String hardDisk) {
   
        computer.setHardDisk(hardDisk);
        return this; // 返回this,支持链式调用
    }

    public ComputerBuilder buildGpu(String gpu) {
   
        computer.setGpu(gpu);
        return this; // 返回this,支持链式调用
    }

    public Computer build() {
   
        return computer; // 返回最终构建的对象
    }
}

客户端代码

public class BuilderPatternDemo {
   
    public static void main(String[] args) {
   
        // 使用链式调用构建对象
        Computer computer = new ComputerBuilder()
                .buildCpu("Intel i7")
                .buildMemory("16GB")
                .buildHardDisk("1TB SSD")
                .buildGpu("NVIDIA RTX 3080")
                .build();

        System.out.println(computer);
    }
}

对比传统建造者模式

  • 传统建造者模式:通过Director类控制构建过程,适合构建过程固定的场景。
  • 链式建造者模式:通过返回this实现链式调用,适合构建过程灵活、需要动态配置的场景。

二、建造者模式在框架源码中的运用

Java中的StringBuilder和StringBuffer

StringBuilderStringBuffer是Java中用于构建字符串的类,它们使用了类似建造者模式的思想,通过链式调用来逐步构建字符串。
示例

StringBuilder builder = new StringBuilder();
builder.append("Hello")
       .append(" ")
       .append("World");
String result = builder.toString();
System.out.println(result); // 输出: Hello World
  • 分析:
    • append方法返回this,支持链式调用。
    • 通过逐步构建字符串,最终调用toString方法生成结果。

Spring Framework中的BeanDefinitionBuilder

在Spring框架中,BeanDefinitionBuilder用于构建BeanDefinition对象,它是Spring IoC容器中定义Bean的核心类。
示例

BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(MyBean.class);
builder.addPropertyValue("name", "MyBeanName")
       .addPropertyValue("age", 30)
       .setScope(BeanDefinition.SCOPE_SINGLETON);

BeanDefinition beanDefinition = builder.getBeanDefinition();
  • 分析:
    • BeanDefinitionBuilder通过链式调用逐步配置Bean的属性。
    • 最终通过getBeanDefinition方法生成BeanDefinition对象。

三、总结

建造者模式的优点

  1. 分离构建与表示
    • 将对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。
    • 客户端不需要知道对象的具体构建细节。
  2. 灵活性和可扩展性
    • 可以逐步构建对象,支持动态配置。
    • 新增构建步骤或修改构建顺序非常方便。
  3. 代码可读性和可维护性
    • 链式调用(Fluent Interface)使代码更加简洁和直观。
    • 将复杂的构建逻辑封装在建造者类中,客户端代码更清晰。
  4. 避免构造方法参数过多
    • 通过逐步设置属性,避免了构造方法参数过长的问题(Telescoping Constructor Problem)。
  5. 保证对象的一致性
    • 对象在完全构建之前不会被使用,确保对象的一致性和完整性。

建造者模式的缺点

  1. 增加代码复杂性
    • 需要额外定义建造者类,增加了类的数量。
    • 对于简单对象,使用建造者模式可能会显得冗余。
  2. 适用范围有限
    • 适用于构建复杂对象,如果对象属性较少或构建过程简单,使用建造者模式可能会过度设计。
  3. 性能开销
    • 由于需要创建建造者对象,可能会引入额外的性能开销(通常可以忽略不计)。

建造者模式的适用场景

  1. 构建复杂对象
    • 当对象有很多属性,且构建过程复杂时,适合使用建造者模式。
    • 例如,构建一个包含多个配置项的计算机对象。
  2. 需要多种表示形式
    • 当同一个构建过程需要生成不同的对象表示时,适合使用建造者模式。
    • 例如,构建不同类型的计算机(游戏计算机、办公计算机等)。
  3. 避免构造方法参数过多
    • 当构造方法参数过多,导致代码难以阅读和维护时,适合使用建造者模式。
  4. 需要逐步构建对象
    • 当对象的构建过程需要分步骤完成时,适合使用建造者模式。
    • 例如,构建一个HTTP请求配置对象。
  5. 框架或工具类中的配置对象
    • 在框架或工具类中,经常需要构建复杂的配置对象,建造者模式非常适合这种场景。
    • 例如,Spring中的BeanDefinitionBuilder、Apache HttpClient中的RequestConfig.Builder等。
目录
相关文章
|
1月前
|
设计模式 Java 数据库连接
【设计模式】【创建型模式】工厂方法模式(Factory Methods)
一、入门 什么是工厂方法模式? 工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它定义了一个用于创建对象的接口,但由子类决定实例化哪个类。工厂方法模式使类的实例化延迟
79 16
|
1月前
|
设计模式 缓存 安全
【设计模式】【创建型模式】单例模式(Singleton)
一、入门 什么是单例模式? 单例模式是一种设计模式,确保一个类只有一个实例,并提供一个全局访问点。它常用于需要全局唯一对象的场景,如配置管理、连接池等。 为什么要单例模式? 节省资源 场景:某些对象创
103 15
|
1月前
|
设计模式 JavaScript Java
【设计模式】【创建型模式】原型模式(Prototype)
一、入门 什么是原型模式? 原型模式(Prototype Pattern)是一种创建型设计模式,它通过复制现有对象来创建新对象,而不是通过实例化类。 原型模式的核心是克隆(Clone),即通过复制现有
81 15
|
1月前
|
设计模式 Java 关系型数据库
【设计模式】【创建型模式】抽象工厂模式(Abstract Factory)
一、入门 什么是抽象工厂模式? 抽象工厂模式是一种创建型设计模式,它提供了一个接口,用于创建相关或依赖对象的家族,而不需要指定具体的类。 简单来说,抽象工厂模式是工厂方法模式的升级版,它能够创建一组相
103 14
|
3月前
|
设计模式 XML Java
设计模式觉醒系列(03)创建型模式的5个设计模式 | 一口气讲全讲透
本文详细介绍了设计模式中的创建型模式,包括建造者模式、原型模式、单例模式、工厂方法模式和抽象工厂模式。创建型模式关注对象的创建过程,隐藏了创建细节,以提高代码的可维护性和可扩展性。通过具体的实战demo和应用场景分析,展示了每种模式的特点和优势。例如,建造者模式适用于复杂对象的分步骤构建;原型模式通过复制对象实现高效复用;单例模式确保全局唯一实例;工厂方法模式和抽象工厂模式则提供了灵活的对象创建机制,支持多类型产品族的生产。这些模式在实际开发中能够简化客户端代码,提升系统灵活性和复用性。
|
9月前
|
设计模式 算法
设计模式--建造者模式 builder
这篇文章通过一个电脑购买的例子,详细解释了建造者模式的四个角色(产品类、抽象构建者、实体构建类和指导者类),并提供了相应的代码实现,阐述了建造者模式在设计复杂对象时的应用和优势。
设计模式--建造者模式 builder
|
6月前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是"将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。创建型模式分为5种:单例模式、工厂方法模式抽象工厂式、原型模式、建造者模式。
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
6月前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
7月前
|
设计模式 架构师 Java
设计模式之 5 大创建型模式,万字长文深剖 ,近 30 张图解!
设计模式是写出优秀程序的保障,是让面向对象保持结构良好的秘诀,与架构能力与阅读源码的能力息息相关,本文深剖设计模式之 5 大创建型模式。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
设计模式之 5 大创建型模式,万字长文深剖 ,近 30 张图解!
|
7月前
|
设计模式 JavaScript Java
Java设计模式:建造者模式详解
建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。本文详细介绍了建造者模式的原理、背景、应用场景及实际Demo,帮助读者更好地理解和应用这一模式。
253 0

热门文章

最新文章