静态工厂方法和构建器模式
静态工厂方法和构建器模式
注意区分“构建器模式”和普通“构造器”(new方法)!
静态工厂方法和构建器模式(Builder Pattern)是两种不同的设计模式,虽然它们都用于对象创建,但解决的问题和适用场景有显著差异。以下是它们的核心区别:
1. 核心目的不同
模式 | 核心目的 |
---|---|
静态工厂方法 | 简化对象创建,隐藏构造细节,提供更灵活的对象实例化方式(例如返回子类、缓存对象等)。 |
构建器模式 | 解决复杂对象的构造问题,尤其是当对象有大量可选参数或需要分步构造时,避免构造函数参数爆炸。 |
2. 典型代码结构对比
静态工厂方法
1
2
3
4
5
6
7
8
9
10
11
12
public class MyClass {
// 静态工厂方法
// 直接根据传入的参数构造对象
public static MyClass create(String param) {
return new MyClass(param);
}
private MyClass(String param) { /* ... */ }
}
// 使用
MyClass obj = MyClass.create("value");
构建器模式
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
public class MyClass {
private final String param1;
private final int param2;
// 构建器
public static class Builder {
private String param1;
private int param2 = 0; // 默认值
// 有不同方法设置对象属性
public Builder param1(String val) {
this.param1 = val;
return this;
}
public Builder param2(int val) {
this.param2 = val;
return this;
}
// 最后生成对象
public MyClass build() {
return new MyClass(this);
}
}
private MyClass(Builder builder) {
this.param1 = builder.param1;
this.param2 = builder.param2;
}
}
// 使用
MyClass obj = new MyClass.Builder()
.param1("value")
.param2(42)
.build();
3. 关键区别
特性 | 静态工厂方法 | 构建器模式 |
---|---|---|
参数处理 | 通常需要一次性传递所有参数(或通过重载) | 支持分步设置参数,可选参数可忽略或设默认值 |
可读性 | 方法名可自解释(如 fromJson ) | 链式调用,参数意义更清晰(如 .name("Alice") ) |
适用场景 | 简单对象创建、对象复用、多态返回 | 复杂对象构造(如含多个可选参数或配置项) |
代码复杂度 | 简单 | 需要额外编写 Builder 类,代码量较多 |
线程安全性 | 通常线程安全(无中间状态) | Builder 的中间状态可能非线程安全 |
典型应用 | Integer.valueOf() 、Collections.emptyList() | StringBuilder 、Flink/Spark 的配置类 |
4. 适用场景示例
静态工厂方法
场景1:隐藏构造函数细节(如返回缓存对象)
1 2 3 4 5 6 7 8
public class Logger { private static final Logger INSTANCE = new Logger(); // 静态工厂方法 public static Logger getInstance() { return INSTANCE; } }
场景2:根据输入返回不同子类
1 2 3 4 5 6
public abstract class Shape { public static Shape create(String type) { if ("circle".equals(type)) return new Circle(); else return new Rectangle(); } }
构建器模式
场景1:构造含多个可选参数的对象
1 2 3 4 5
HttpClient client = new HttpClient.Builder() .url("https://example.com") .timeout(5000) .retry(3) .build();
场景2:分步配置复杂对象(如 Flink 的
StreamExecutionEnvironment
)1 2 3 4
FileSink<String> sink = FileSink.forRowFormat(...) .withBucketAssigner(...) .withRollingPolicy(...) .build();
5. 为什么不能混用?
- 静态工厂方法 可以返回任意对象(包括不同子类或缓存实例),但不解决参数过多的问题。
- 构建器模式 专门解决参数过多和可选参数问题,但需要为每个类单独实现 Builder。
总结
模式 | 用一句话概括 |
---|---|
静态工厂方法 | “通过一个静态方法,直接给你一个对象。” |
构建器模式 | “通过链式调用一步步配置参数,最后生成一个对象。” |
根据需求选择:
- 若对象简单且参数少 → 静态工厂方法。
- 若对象复杂、参数多或需分步配置 → 构建器模式。
This post is licensed under CC BY 4.0 by the author.