建造者模式(Builder Pattern)

定义

建造者模式是一种​​创建型设计模式​​,用于分步骤构造复杂对象。它通过将对象的构建过程与表示分离,使得同样的构建过程可以创建不同的对象形态。


UML 类图​

设计模式之创建型:建造者模式_建造者模式

  • Director(指挥者)​​:控制构建流程(定义步骤顺序),不依赖具体 Builder。
  • ​​Builder(抽象建造者)​​:声明构建对象的步骤方法(如 buildPartA())。
  • ​​ConcreteBuilder​(具体建造者)​​:实现构建逻辑,生成具体产品。
  • ​​Product​(最终构建的复杂对象)​​:包含多个组成部分。

优点​

  • 分步构建​​:允许精细控制构造顺序,支持延迟构造或递归步骤(如先验证后初始化)。
  • 灵活扩展​​:新增 ConcreteBuilder 即可支持不同对象配置,符合开闭原则。
  • 封装性​​:隐藏复杂对象的内部结构,客户端无需了解构建细节。
  • 单一职责​​:构造逻辑与业务逻辑分离,职责清晰。

缺点​​

  • 代码冗余​​:需为每个产品编写独立的 Builder 类,增加代码量。
  • ​​产品共性约束​​:所有产品必须遵循相同接口,否则需引入额外抽象层。
  • ​​构造过程固化​​:若构建步骤频繁变化,需频繁修改 Builder 接口。

适用场景​

  • 复杂对象构造​​:对象包含多个组件(如汽车、计算机、配置文件)。
// 示例:计算机对象包含 CPU、内存、硬盘等组件
Computer computer = new ComputerBuilder()
    .setCPU("Intel i9")
    .setRAM("32GB")
    .setStorage("1TB SSD")
    .build();
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 多种对象配置​​:需根据参数生成不同形态对象(如高配/低配电脑、XML/JSON 格式导出)。
// 示例:生成高配和低配电脑
Builder highEndBuilder = new HighEndComputerBuilder();
Builder lowEndBuilder = new LowEndComputerBuilder();
  • 1.
  • 2.
  • 3.
  • ​​分步初始化​​:对象构造需严格分步骤完成(如数据库连接池初始化)。
// 示例:数据库连接池分步构造
ConnectionPool pool = new ConnectionPoolBuilder()
    .setMaxConnections(100)
    .setTimeout(5000)
    .enableMetrics(true)
    .build();
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • ​​避免重叠构造器​​:替代含多个可选参数的冗长构造器(如 new Product(a, b, c, d…))。
// 传统构造器 vs 建造者模式
User user = new User("Alice", 30, "alice@example.com", "admin", true); // 易混淆参数顺序
User user = new UserBuilder().name("Alice").age(30).email("alice@example.com").build(); // 清晰
  • 1.
  • 2.
  • 3.

常见的建造者模式源码案例

基础建造者模式​

场景​​:分步骤构造一个计算机对象(CPU + 内存 + 硬盘)

// 产品类:计算机
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; }

    public void showSpecs() {
        System.out.println("CPU: " + cpu + ", RAM: " + ram + ", Storage: " + storage);
    }
}

// 抽象建造者
interface ComputerBuilder {
    void buildCPU();
    void buildRAM();
    void buildStorage();
    Computer getResult();
}

// 具体建造者:游戏电脑
class GamingComputerBuilder implements ComputerBuilder {
    private Computer computer = new Computer();

    @Override
    public void buildCPU() { computer.setCPU("Intel i9"); }
    @Override
    public void buildRAM() { computer.setRAM("32GB DDR5"); }
    @Override
    public void buildStorage() { computer.setStorage("1TB SSD"); }
    @Override
    public Computer getResult() { return computer; }
}

// 指挥者(可选)
class Director {
    public void construct(ComputerBuilder builder) {
        builder.buildCPU();
        builder.buildRAM();
        builder.buildStorage();
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        Director director = new Director();
        ComputerBuilder builder = new GamingComputerBuilder();
        director.construct(builder); // 指挥者控制构造流程
        Computer computer = builder.getResult();
        computer.showSpecs(); // 输出:CPU: Intel i9, RAM: 32GB DDR5, Storage: 1TB SSD
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.

扩展建造者模式(支持可选参数)​​

场景​​:构造用户对象,部分参数可选(如地址、电话)

// 产品类:用户
class User {
    private final String name;    // 必选
    private final int age;       // 必选
    private String address;      // 可选
    private String phone;        // 可选

    // 私有构造器,只能通过 Builder 创建
    private User(Builder builder) {
        this.name = builder.name;
        this.age = builder.age;
        this.address = builder.address;
        this.phone = builder.phone;
    }

    // 静态内部 Builder 类
    public static class Builder {
        private final String name;
        private final int age;
        private String address = "Unknown";
        private String phone = "N/A";

        // 必选参数通过构造器传入
        public Builder(String name, int age) {
            this.name = name;
            this.age = age;
        }

        // 可选参数通过链式方法设置
        public Builder address(String address) {
            this.address = address;
            return this;
        }

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

        // 构建最终对象,可在此处添加校验逻辑
        public User build() {
            if (age < 0) throw new IllegalArgumentException("年龄不能为负数");
            return new User(this);
        }
    }

    public void showInfo() {
        System.out.println("Name: " + name + ", Age: " + age + ", Address: " + address + ", Phone: " + phone);
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        User user = new User.Builder("Alice", 30)
                .address("New York")
                .phone("123-456-7890")
                .build();
        user.showInfo(); // 输出:Name: Alice, Age: 30, Address: New York, Phone: 123-456-7890
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.

线程安全建造者模式​

场景​​:多线程环境下构造不可变对象

// 不可变的产品类
final class Configuration {
    private final String host;
    private final int port;
    private final boolean sslEnabled;

    private Configuration(Builder builder) {
        this.host = builder.host;
        this.port = builder.port;
        this.sslEnabled = builder.sslEnabled;
    }

    // 静态内部 Builder 类(方法同步)
    public static class Builder {
        private String host = "localhost";
        private int port = 8080;
        private boolean sslEnabled = false;

        public synchronized Builder setHost(String host) {
            this.host = host;
            return this;
        }

        public synchronized Builder setPort(int port) {
            if (port < 0) throw new IllegalArgumentException("端口号无效");
            this.port = port;
            return this;
        }

        public synchronized Builder enableSSL(boolean sslEnabled) {
            this.sslEnabled = sslEnabled;
            return this;
        }

        public synchronized Configuration build() {
            return new Configuration(this);
        }
    }

    public void showConfig() {
        System.out.println("Host: " + host + ", Port: " + port + ", SSL: " + sslEnabled);
    }
}

// 客户端调用(多线程安全)
public class Client {
    public static void main(String[] args) {
        Configuration config = new Configuration.Builder()
                .setHost("api.example.com")
                .setPort(443)
                .enableSSL(true)
                .build();
        config.showConfig(); // 输出:Host: api.example.com, Port: 443, SSL: true
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.

链式调用简化版(无 Director)​

​场景​​:快速构造订单对象(商品列表 + 收货地址)

// 产品类:订单
class Order {
    private List<String> items;
    private String address;

    private Order() {} // 私有构造器

    public void showOrder() {
        System.out.println("Items: " + items + ", Address: " + address);
    }

    // 内部 Builder 类
    public static class Builder {
        private Order order = new Order();

        public Builder addItem(String item) {
            if (order.items == null) order.items = new ArrayList<>();
            order.items.add(item);
            return this;
        }

        public Builder setAddress(String address) {
            order.address = address;
            return this;
        }

        public Order build() {
            if (order.items == null || order.items.isEmpty()) {
                throw new IllegalStateException("订单必须包含至少一件商品");
            }
            return order;
        }
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        Order order = new Order.Builder()
                .addItem("Book")
                .addItem("Pen")
                .setAddress("Beijing")
                .build();
        order.showOrder(); // 输出:Items: [Book, Pen], Address: Beijing
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.

结合 Lombok 的简化实现

import lombok.Builder;
import lombok.ToString;

@Builder
@ToString
public class Product {
    private String id;
    private String name;
    private double price;
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        Product product = Product.builder()
                .id("P001")
                .name("Laptop")
                .price(999.99)
                .build();
        System.out.println(product); // 输出:Product(id=P001, name=Laptop, price=999.99)
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.

建造者模式核心总结

实现方式适用场景关键特点
基础建造者模式严格分步骤构造复杂对象(如计算机组装)分离构建过程与表示,通过指挥者控制流程,支持多态化构建
扩展建造者模式包含可选参数的对象构造(如用户信息)链式方法设置参数,支持必选/可选字段分离,可添加构建校验逻辑
线程安全建造者模式多线程环境下的不可变对象(如配置类)使用synchronized方法保证原子性,构造器私有化防止外部修改
链式调用简化版快速构造简单对象(如订单)省略指挥者角色,直接通过Builder链式调用完成构建,适合轻量级场景
Lombok @Builder快速开发POJO/DTO类(如API响应对象)自动生成标准建造者代码,通过注解配置字段默认值,显著减少样板代码

场景选择建议

  • 高复杂度对象 → 基础/扩展建造者模式
  • 高频简单对象 → Lombok/链式简化版
  • 多线程共享配置 → 线程安全建造者模式