一句话总结:
建造者模式就像「乐高说明书」—— 分步骤组装复杂对象,Android 里的 AlertDialog、Notification 都用它告别构造器爆炸,让代码优雅如诗!
一、建造者模式在 Android 的经典应用
1. AlertDialog 的链式调用
// 使用建造者模式创建对话框
AlertDialog dialog = new AlertDialog.Builder(context)
.setTitle("警告")
.setMessage("确定删除?")
.setPositiveButton("确定", (d, which) -> { /* 处理点击 */ })
.setNegativeButton("取消", null)
.create();
dialog.show();
源码实现:
// frameworks/base/core/java/android/app/AlertDialog.java
public static class Builder {
private final AlertController.AlertParams P;
public Builder(Context context) {
P = new AlertController.AlertParams(context);
}
public Builder setTitle(CharSequence title) {
P.mTitle = title;
return this;
}
public AlertDialog create() {
final AlertDialog dialog = new AlertDialog(P.mContext);
P.apply(dialog.mAlert); // 将参数应用到 AlertController
return dialog;
}
}
// 参数存储类
public static class AlertParams {
public CharSequence mTitle;
public CharSequence mMessage;
// ... 其他 30+ 参数
}
设计亮点:
- 参数集中管理:所有配置项存储在
AlertParams中 - 构造延迟:直到
create()才真正创建AlertDialog对象 - 链式调用:每个
set方法返回this,提升可读性
二、底层设计原理剖析
1. 避免构造器爆炸(Telescoping Constructor)
传统构造器缺陷:
// 传统方式需要多个重载构造器
public AlertDialog(
Context context, String title, String message,
String positiveText, OnClickListener positiveListener,
String negativeText, OnClickListener negativeListener,
/* 更多参数... */ ) {
// 构造器臃肿难以维护
}
建造者模式优势:
- 可选参数灵活处理:30+ 参数中大部分有默认值
- 强制必填参数:通过 Builder 构造函数实现(如
Builder(Context)必须传 Context)
2. 参数校验与默认值
// 在 apply() 方法中处理默认逻辑
public void apply(AlertController dialog) {
if (mTitle != null) dialog.setTitle(mTitle);
if (mMessage != null) dialog.setMessage(mMessage);
if (mPositiveButtonText != null) {
dialog.setButton(DialogInterface.BUTTON_POSITIVE,
mPositiveButtonText, mPositiveButtonListener);
}
// 设置默认取消行为
dialog.setOnCancelListener(mOnCancelListener);
}
3. 与系统资源的深度整合
// 通过 Context 获取主题样式
public Builder(Context context) {
this(context, resolveDialogTheme(context, 0));
}
// 解析对话框主题
static int resolveDialogTheme(Context context, int resid) {
if (resid == 0) return R.style.Theme_DeviceDefault_Dialog_Alert;
return resid;
}
三、建造者模式 vs 其他创建型模式
| 模式 | 核心区别 | Android 案例 |
|---|---|---|
| 建造者模式 | 分步构建复杂对象,参数灵活 | AlertDialog.Builder |
| 工厂模式 | 直接创建对象,关注产品类型 | BitmapFactory |
| 原型模式 | 通过克隆生成对象,避免重复初始化成本 | Parcelable 的 copy |
四、高级应用:自定义建造者模式
1. 网络请求配置建造者
public class RequestBuilder {
private String url;
private Map<String, String> params;
private int timeout = 5000;
public RequestBuilder(String url) {
this.url = url;
}
public RequestBuilder addParam(String key, String value) {
if (params == null) params = new HashMap<>();
params.put(key, value);
return this;
}
public Request build() {
return new Request(url, params, timeout);
}
}
// 使用方式
Request request = new RequestBuilder("https://api.example.com")
.addParam("page", "1")
.addParam("size", "20")
.build();
2. 结合 Parcelable 实现高效传输
// 使用建造者模式构建跨进程数据
public class User implements Parcelable {
private final String name;
private final int age;
public static class Builder {
private String name = "Anonymous";
private int age = 18;
public Builder setName(String name) {
this.name = name;
return this;
}
public User build() {
return new User(this);
}
}
private User(Builder builder) {
name = builder.name;
age = builder.age;
}
// Parcelable 实现...
}
五、源码中的隐藏技巧
1. 重用 Builder 配置
// 克隆现有配置创建新 Builder
AlertDialog.Builder originalBuilder = new AlertDialog.Builder(context)
.setTitle("原始标题");
AlertDialog.Builder newBuilder = new AlertDialog.Builder(context)
.applyFrom(originalBuilder) // 复制原有配置
.setMessage("新增内容");
2. 内存优化技巧
// 使用后重置 Builder 避免内存泄漏
public AlertDialog create() {
AlertDialog dialog = new AlertDialog(P.mContext);
P.apply(dialog.mAlert);
P.clear(); // 清空参数引用
return dialog;
}
六、总结口诀
「构造复杂对象难,建造者来分步干
链式调用真优雅,参数灵活不爆炸
AlertDialog 是典范,自定义时照此办
使用场景建议:
- 需要 4 个以上参数的复杂对象
- 参数之间存在依赖关系(如必须先设置类型才能设置其他参数)
- 需要支持多配置组合(如不同主题的通知)
注意事项:
- 避免在 Builder 中保存 Context 引用(可能导致内存泄漏)
- 必要时对参数进行合法性校验(如检查 URL 格式)
- 线程安全考虑(若在多线程中使用需加同步锁)