建造者模式 (Builder Pattern)

定义:

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

建造者模式的关键特点包括:

  1. 分离复杂对象的构造和表示
    • 允许客户端不必了解内部组成的细节,就可以构造复杂的对象。通常用于创建具有多个部分的对象,特别是当这些部分需要通过多个步骤进行构建时。
  2. 提供控制复杂性的方法
    • 通过一个指导者(Director)和多个不同的建造者(Builder)实现,指导者负责按照特定步骤构建产品,而建造者提供这些步骤的具体实现。
  3. 流畅的接口风格
    • 建造者模式经常以链式调用(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对象
    }
}
主要符合的设计原则:
  1. 单一职责原则(Single Responsibility Principle)
    • 建造者模式通过将复杂对象的构造过程从其表示中分离出来,使得构造过程和表示方法有单一的职责。构造逻辑在建造者中实现,而对象的表示则在产品类中。
  2. 开闭原则(Open-Closed Principle)
    • 建造者模式支持开闭原则,因为可以在不修改现有代码的情况下引入新的类型的建造者。如果需要创建一个新类型的对象,你只需要添加一个新的具体建造者类。
  3. 里氏替换原则(Liskov Substitution Principle)
    • 尽管建造者模式不直接体现里氏替换原则,但它允许扩展建造者,新的建造者继承基本建造者时,可以替换基本建造者而不影响指导者的使用。
  4. 接口隔离原则(Interface Segregation Principle)
    • 建造者模式通常使用接口来定义建造者的方法,这些接口仅暴露必要的方法,从而遵守接口隔离原则。
  5. 依赖倒转原则(Dependency Inversion Principle)
    • 在建造者模式中,指导者类(Director)依赖于建造者接口(Builder),而不是具体的建造者实现类。这样做降低了指导者和具体建造者之间的耦合,符合依赖倒转原则。

综上所述,建造者模式通过上述原则的应用,提高了代码的模块化和灵活性,降低了各个类之间的耦合。

在JDK中的应用:
  • java.lang.StringBuilder / java.lang.StringBuffer
    • StringBuilderStringBuffer 类在构建字符串时采用了建造者模式。这些类提供了链式方法调用来逐步构建和修改字符串,最后通过 toString() 方法返回最终的字符串对象。
  • java.nio.ByteBuffer
    • 在Java NIO中,ByteBuffer 类及其兄弟类(如 CharBuffer, ShortBuffer 等)提供了一种类似建造者模式的方法来构建和操作缓冲区。例如,可以链式调用 put() 方法向缓冲区添加数据。
  • java.sql.PreparedStatement
    • 在JDBC API中,PreparedStatement 类使用类似建造者模式的方法来逐步构建SQL语句。通过一系列的 setXxx() 方法设置参数,最后执行查询或更新。
  • Java Stream API
    • 在Java 8及以上版本中,Stream API使用类似建造者模式的链式调用来构建和处理数据流。例如,可以通过一系列的中间操作(如 filter, map)构建数据流,最后通过终端操作(如 collect, forEach)完成数据处理。
在Spring中的应用:
  • Spring Security的配置
    • 在Spring Security中,安全配置通常通过一个流畅的接口实现,这允许通过链式方法调用来构建安全约束。例如,.http().authorizeRequests().antMatchers("/admin").hasRole("ADMIN").and().formLogin() 这样的配置就是使用建造者模式来实现的。
  • RestTemplate Builder
    • 在Spring提供的 RestTemplateBuilder 类中,建造者模式被用来构建 RestTemplate 实例。这种方式允许客户端在构建 RestTemplate 时灵活地添加定制化的功能,如消息转换器、请求工厂、拦截器等。
  • Spring Boot的ApplicationBuilder
    • 在Spring Boot中,SpringApplicationBuilder 类用于构建和配置 SpringApplicationApplicationContext。它提供了一种流畅的API来定制Spring应用的行为。
  • Spring Framework的UriComponentsBuilder
    • UriComponentsBuilder 是用于构建URI的工具类,提供了一种流畅的API来构建 UriComponents 实例,这是建造者模式的典型应用。

在这些例子中,建造者模式允许通过一个简洁且易读的接口逐步构建复杂对象。它使得代码更加清晰,并且可以灵活地构建对象,而不必担心对象的构建过程中的细节。这种模式在需要构建配置复杂的对象时特别有用,如在配置安全性、创建REST客户端或构建复杂的URI时。


你可能感兴趣的:(设计模式,建造者模式,java,开发语言,设计模式)