Builder 模式:两种实现方式对比

#设计模式 #Builder模式 #动态线程池

Builder 模式:两种实现方式对比

一、简化 Builder(单一 Builder 类)

代码示例

public class ThreadFactoryBuilder {

    /**
     * 基础线程工厂,默认使用 Executors.defaultThreadFactory()
     */
    private ThreadFactory backingThreadFactory;

    /**
     * 线程名前缀,如 "onethread-",线程名形如:onethread-1
     */
    private String namePrefix;

    /**
     * 是否为守护线程,默认 false
     */
    private Boolean daemon;

    /**
     * 线程优先级(1~10)
     */
    private Integer priority;

    /**
     * 未捕获异常处理器
     */
    private Thread.UncaughtExceptionHandler uncaughtExceptionHandler;

    /**
     * 创建 ThreadFactoryBuilder 实例
     */
    public static ThreadFactoryBuilder builder() {
        return new ThreadFactoryBuilder();
    }

    public ThreadFactoryBuilder threadFactory(ThreadFactory backingThreadFactory) {
        this.backingThreadFactory = backingThreadFactory;
        return this;
    }

    public ThreadFactoryBuilder namePrefix(String namePrefix) {
        this.namePrefix = namePrefix;
        return this;
    }

    public ThreadFactoryBuilder daemon(boolean daemon) {
        this.daemon = daemon;
        return this;
    }

    public ThreadFactoryBuilder priority(int priority) {
        if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
            throw new IllegalArgumentException("The thread priority must be between 1 and 10.");
        }
        this.priority = priority;
        return this;
    }

    public ThreadFactoryBuilder uncaughtExceptionHandler(Thread.UncaughtExceptionHandler handler) {
        this.uncaughtExceptionHandler = handler;
        return this;
    }

    /**
     * 构建线程工厂实例(返回另一个类型)
     */
    public ThreadFactory build() {
        final ThreadFactory factory = (this.backingThreadFactory != null)
            ? this.backingThreadFactory
            : Executors.defaultThreadFactory();

        Assert.notEmpty(namePrefix, "The thread name prefix cannot be empty or an empty string.");
        final AtomicLong count = (StrUtil.isNotBlank(namePrefix)) ? new AtomicLong(0) : null;

        return runnable -> {
            Thread thread = factory.newThread(runnable);

            if (count != null) {
                thread.setName(namePrefix + count.getAndIncrement());
            }

            if (daemon != null) {
                thread.setDaemon(daemon);
            }

            if (priority != null) {
                thread.setPriority(priority);
            }

            if (uncaughtExceptionHandler != null) {
                thread.setUncaughtExceptionHandler(uncaughtExceptionHandler);
            }

            return thread;
        };
    }
}

结构特征

┌─────────────────────────────────┐
│   ThreadFactoryBuilder          │  ← Builder 类(可变)
│  ─────────────────────────      │
│  - namePrefix: String           │
│  - daemon: Boolean              │
│  - priority: Integer            │
│  ─────────────────────────      │
│  + builder(): Builder           │  ← 返回自己
│  + namePrefix(String): Builder  │  ← 链式调用
│  + daemon(boolean): Builder     │
│  + build(): ThreadFactory       │  ← 返回另一个类型
└─────────────────────────────────┘
              ↓ build()
┌─────────────────────────────────┐
│   ThreadFactory                 │  ← 目标对象
│  (interface/functional object)  │
└─────────────────────────────────┘

核心特点

  • Builder 是独立类,既是配置器也是构建器
  • build() 返回另一个类型的对象
  • 目标对象通常不需要保持不可变
  • 代码简单,只有一个类

二、经典 Builder(嵌套 Builder 类)

代码示例

/**
 * 线程池配置 - 经典 Builder 模式(不可变对象)
 */
public class ThreadPoolConfig {

    // ===== 目标类的字段(final = 不可变) =====
    private final int corePoolSize;
    private final int maxPoolSize;
    private final int queueCapacity;
    private final String threadNamePrefix;
    private final long keepAliveTime;
    private final TimeUnit timeUnit;

    // ===== 私有构造器(只能通过 Builder 创建) =====
    private ThreadPoolConfig(Builder builder) {
        this.corePoolSize = builder.corePoolSize;
        this.maxPoolSize = builder.maxPoolSize;
        this.queueCapacity = builder.queueCapacity;
        this.threadNamePrefix = builder.threadNamePrefix;
        this.keepAliveTime = builder.keepAliveTime;
        this.timeUnit = builder.timeUnit;
    }

    // ===== 静态工厂方法(返回 Builder 实例) =====
    public static Builder builder() {
        return new Builder();
    }

    // ===== Getter 方法(没有 Setter,保证不可变) =====
    public int getCorePoolSize() { return corePoolSize; }
    public int getMaxPoolSize() { return maxPoolSize; }
    public int getQueueCapacity() { return queueCapacity; }
    public String getThreadNamePrefix() { return threadNamePrefix; }
    public long getKeepAliveTime() { return keepAliveTime; }
    public TimeUnit getTimeUnit() { return timeUnit; }

    // ===== 静态内部 Builder 类 =====
    public static class Builder {

        // Builder 拥有与目标类相同的字段(可变)
        private int corePoolSize = 1;               // 默认值
        private int maxPoolSize = 10;               // 默认值
        private int queueCapacity = 100;            // 默认值
        private String threadNamePrefix = "pool-";  // 默认值
        private long keepAliveTime = 60L;
        private TimeUnit timeUnit = TimeUnit.SECONDS;

        // 私有构造器(强制使用外部类的 builder() 方法)
        private Builder() {
        }

        // ===== 链式 setter 方法(返回 Builder) =====
        public Builder corePoolSize(int corePoolSize) {
            this.corePoolSize = corePoolSize;
            return this;
        }

        public Builder maxPoolSize(int maxPoolSize) {
            this.maxPoolSize = maxPoolSize;
            return this;
        }

        public Builder queueCapacity(int queueCapacity) {
            this.queueCapacity = queueCapacity;
            return this;
        }

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

        public Builder keepAliveTime(long keepAliveTime, TimeUnit timeUnit) {
            this.keepAliveTime = keepAliveTime;
            this.timeUnit = timeUnit;
            return this;
        }

        // ===== build() 方法(返回目标类实例) =====
        public ThreadPoolConfig build() {
            // 统一验证所有参数
            validate();

            // 创建并返回目标类的不可变实例
            return new ThreadPoolConfig(this);
        }

        // ===== 参数验证 =====
        private void validate() {
            if (corePoolSize <= 0) {
                throw new IllegalArgumentException("corePoolSize 必须大于 0");
            }
            if (maxPoolSize < corePoolSize) {
                throw new IllegalArgumentException("maxPoolSize 不能小于 corePoolSize");
            }
            if (queueCapacity <= 0) {
                throw new IllegalArgumentException("queueCapacity 必须大于 0");
            }
            if (threadNamePrefix == null || threadNamePrefix.isEmpty()) {
                throw new IllegalArgumentException("threadNamePrefix 不能为空");
            }
            if (keepAliveTime < 0) {
                throw new IllegalArgumentException("keepAliveTime 不能为负数");
            }
        }
    }

    // ===== 便捷方法(如创建线程池) =====
    public ThreadPoolExecutor createExecutor() {
        return new ThreadPoolExecutor(
            corePoolSize,
            maxPoolSize,
            keepAliveTime,
            timeUnit,
            new LinkedBlockingQueue<>(queueCapacity),
            ThreadFactoryBuilder.builder()
                .namePrefix(threadNamePrefix)
                .build()
        );
    }

    @Override
    public String toString() {
        return "ThreadPoolConfig{" +
                "corePoolSize=" + corePoolSize +
                ", maxPoolSize=" + maxPoolSize +
                ", queueCapacity=" + queueCapacity +
                ", threadNamePrefix='" + threadNamePrefix + '\'' +
                ", keepAliveTime=" + keepAliveTime +
                ", timeUnit=" + timeUnit +
                '}';
    }
}

结构特征

┌─────────────────────────────────────┐
│      ThreadPoolConfig               │  ← 目标类(不可变)
│  ────────────────────────────       │
│  - final corePoolSize: int          │
│  - final maxPoolSize: int           │
│  - final queueCapacity: int         │
│  ────────────────────────────       │
│  - ThreadPoolConfig(Builder)        │  ← 私有构造器
│  + builder(): Builder               │  ← 返回内部 Builder
│  + getCorePoolSize(): int           │
└─────────────────────────────────────┘
              │ 包含
┌─────────────────────────────────────┐
│      ThreadPoolConfig.Builder       │  ← 内部 Builder(可变)
│  ────────────────────────────       │
│  - corePoolSize: int                │  ← 与目标类相同的字段
│  - maxPoolSize: int                 │
│  - queueCapacity: int               │
│  ────────────────────────────       │
│  + corePoolSize(int): Builder       │  ← 链式调用
│  + maxPoolSize(int): Builder        │
│  + build(): ThreadPoolConfig        │  ← 返回外部类实例
└─────────────────────────────────────┘

核心特点

  • Builder 是目标类的静态内部类
  • 目标类所有字段 final(不可变)
  • build() 返回目标类实例
  • 清晰分离"构建过程"和"最终对象"

三、两种模式对比

对比表

维度 简化 Builder(单一类) 经典 Builder(嵌套类)
类数量 1 个类 2 个类(外部类 + 内部 Builder)
Builder 返回值 build() 返回另一个类型 build() 返回外部类实例
目标对象 可以是可变的 严格不可变(所有字段 final)
字段访问 Builder 和目标对象字段分开 Builder 复制外部类字段
验证时机 可以在 setter 和 build() 都验证 通常只在 build() 统一验证
默认值 在 Builder 字段初始化 在 Builder 字段初始化
复杂度 简单 较复杂
类型安全 较低(Builder 可变) 高(目标对象不可变)
线程安全 需要额外处理 天然线程安全(不可变)

使用方式对比

// ===== 简化 Builder =====
ThreadFactory factory = ThreadFactoryBuilder.builder()
    .namePrefix("async-pool-")
    .daemon(true)
    .priority(7)
    .build();  // 返回 ThreadFactory(另一个类型)

ExecutorService executor = Executors.newFixedThreadPool(10, factory);

// ===== 经典 Builder =====
ThreadPoolConfig config = ThreadPoolConfig.builder()
    .corePoolSize(5)
    .maxPoolSize(20)
    .queueCapacity(200)
    .threadNamePrefix("order-service-")
    .keepAliveTime(120, TimeUnit.SECONDS)
    .build();  // 返回 ThreadPoolConfig(不可变对象)

ThreadPoolExecutor executor = config.createExecutor();
// config 不可变,线程安全

四、使用场景决策

决策树

flowchart TD A[需要构建复杂对象] --> B{目标对象需要
不可变性?} B -->|是| C[经典 Builder
嵌套类模式] B -->|否| D{Builder 是
目标对象本身?} D -->|是| C D -->|否| E[简化 Builder
单一类模式] C --> F[适用场景
• 配置对象
• 领域实体
• 需要线程安全] E --> G[适用场景
• 工厂/工具类
• 函数对象
• 临时对象]

场景 1:工厂/工具类 → 简化 Builder

特征

  • Builder 是工具,用来创建另一个类型的对象
  • 不需要保持不可变性
  • 重点是"构建过程",而非"最终对象"

实际例子

// 1. ThreadFactoryBuilder → ThreadFactory
ThreadFactoryBuilder.builder()
    .namePrefix("async-")
    .build()  // 返回 ThreadFactory

// 2. StringBuilder → String
new StringBuilder()
    .append("Hello")
    .toString()  // 返回 String

// 3. Stream.Builder → Stream
Stream.builder()
    .add("A")
    .build()  // 返回 Stream

// 4. UriBuilder → URI
UriBuilder.fromUri("https://api.example.com")
    .path("/users")
    .queryParam("limit", 10)
    .build();  // 返回 URI

// 5. RestClient.Builder → RestClient
RestClient.builder()
    .baseUrl("https://api.example.com")
    .build();  // 返回 RestClient

适用条件

  • 目标对象是另一个类型(工厂、接口、匿名函数)
  • Builder 用完即弃,不需要长期存在
  • 不需要严格的不可变性

场景 2:配置/实体对象 → 经典 Builder

特征

  • 目标对象需要不可变(线程安全)
  • 参数需要验证(避免非法状态)
  • 对象会在多个地方传递和使用

实际例子

// 1. 线程池配置
ThreadPoolConfig config = ThreadPoolConfig.builder()
    .corePoolSize(5)
    .maxPoolSize(20)
    .threadNamePrefix("order-")
    .build();
// config 不可变,线程安全

// 2. HTTP 客户端配置
OkHttpClient client = new OkHttpClient.Builder()
    .connectTimeout(10, TimeUnit.SECONDS)
    .readTimeout(30, TimeUnit.SECONDS)
    .addInterceptor(new LoggingInterceptor())
    .build();
// client 不可变,可以安全共享

// 3. 用户对象(领域模型)
User user = User.builder()
    .id("123")
    .name("Alice")
    .email("alice@example.com")
    .build();
// user 不可变,防止业务逻辑意外修改

// 4. Guava 不可变集合
ImmutableSet<String> set = ImmutableSet.builder()
    .add("A")
    .add("B")
    .build();
// set 不可变,强制不可修改

// 5. RocketMQ 消息
Message msg = Message.builder()
    .topic("order-created")
    .body(orderJson)
    .tag("payment")
    .key(orderId)
    .build();
// msg 不可变,保证消息一致性

适用条件

  • 需要不可变性(线程安全、防止意外修改)
  • 需要严格验证(build 时检查所有参数)
  • 对象会长期存在或在多线程间传递

五、优缺点总结

简化 Builder(单一类)

优点

  • 简单直接,只有一个类
  • 代码量少,易于理解
  • 适合工厂/工具场景

缺点

  • 目标对象可变(如果需要不可变,需要额外处理)
  • 类型安全性较低
  • 不适合复杂领域对象

经典 Builder(嵌套类)

优点

  • 目标对象严格不可变(线程安全)
  • 类型安全,编译时保证
  • 统一验证,避免非法状态
  • 清晰分离"构建过程"和"最终对象"

缺点

  • 代码量大(需要维护两套字段)
  • 相对复杂
  • 对于简单场景可能过度设计

六、实战建议

1. 项目中如何选择?

// 使用简化 Builder:ThreadFactoryBuilder
// 原因:它是工具,用来创建 ThreadFactory
public class ThreadFactoryBuilder {
    public ThreadFactory build() { /* ... */ }
}

// 使用经典 Builder:DynamicThreadPoolConfig
// 原因:配置对象需要不可变,会被多个地方引用
public class DynamicThreadPoolConfig {
    private final String poolName;
    private final int coreSize;
    // ...

    public static class Builder {
        public DynamicThreadPoolConfig build() { /* ... */ }
    }
}

2. 混合使用

// 配置对象用经典 Builder(不可变)
DynamicThreadPoolConfig config = DynamicThreadPoolConfig.builder()
    .corePoolSize(10)
    .maxPoolSize(20)
    .build();

// 线程工厂用简化 Builder(工具)
ThreadFactory factory = ThreadFactoryBuilder.builder()
    .namePrefix(config.getPoolName() + "-")
    .build();

// 创建线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    config.getCorePoolSize(),
    config.getMaxPoolSize(),
    // ...
);

3. 使用 Lombok 简化经典 Builder

// 使用 @Builder 自动生成经典 Builder
@Builder
public class DynamicThreadPoolConfig {
    private final String poolName;
    private final int corePoolSize;
    private final int maxPoolSize;
    private final int queueCapacity;

    // 手动添加验证
    public static class Builder {
        public DynamicThreadPoolConfig build() {
            if (corePoolSize <= 0) {
                throw new IllegalArgumentException("corePoolSize 必须大于 0");
            }
            return new DynamicThreadPoolConfig(this);
        }
    }
}

// 使用方式
DynamicThreadPoolConfig config = DynamicThreadPoolConfig.builder()
    .poolName("order-service")
    .corePoolSize(10)
    .maxPoolSize(20)
    .build();

七、快速选择指南

场景 推荐模式 典型例子
工厂/工具类 简化 Builder ThreadFactoryBuilder → ThreadFactory
配置对象 经典 Builder ThreadPoolConfig
领域实体 经典 Builder User、Order
集合构建 简化 Builder ImmutableList.builder()
流式 API 简化 Builder Stream.Builder
不可变需求 经典 Builder OkHttpClient

核心原则

  1. 需要不可变性 → 经典 Builder(嵌套类)
  2. 创建其他类型 → 简化 Builder(单一类)
  3. 简单工具 → 简化 Builder(单一类)
  4. 复杂配置 → 经典 Builder(嵌套类)