1.简述
Java的Builder机制,主要是将复杂对象的构建构建过程与其具体表示分离, 使得相同的构建流程可以创建不同的产品实例。Builder模式是一种创建型 设计模式,针对复杂对象构建,复杂对象主要表现:
1.1 多参数构造器
- 问题1:参数顺序的混乱 比如:HttpParam(url, method, params, headers, timeout, cache)等等,顺序容易搞混。
- 问题2:重载爆炸
为了支持可选参数,需要写多个重载构造器,比如,支持仅传递url, 仅传递url+method的...
Builder方案,通过链式调用,明确参数含义,无需关心顺序,可以选参数进行设置### 1.2 保证对象的不可变性,线程安全 理想设计的目标,应该将HttpParam 设计为 不可变对象,所有字段final, 无setter方法,构建后无法修改,天然线程安全。 Builder 方案:所有参数在 build() 方法中一次性赋值给不可变字段,构建完成后对象状态完全确定,不存在「半成品对象」。
HttpParam param = new HttpParam.Builder() .url("https://api.example.com") .method("POST") .timeout(1000) .cache(true) .headers(headers) .build(); // 最终构建对象
2. 实例展示
实际开发中,已网络请求参数为例进行讲解,
import java.util.HashMap;
import java.util.Map;
/**
* 网络请求参数实体类(不可变设计)
*/
public class HttpRequestParam {
// 核心字段:必选参数(url/method)+ 可选参数(headers/params/timeout)
private final String url; // 必选:请求地址
private final String method; // 必选:请求方法(GET/POST)
private final Map<String, String> headers; // 可选:请求头
private final Map<String, String> params; // 可选:请求参数(Query/Form)
private final int timeout; // 可选:超时时间(默认3000ms)
// 关键:私有构造器,仅允许 Builder 内部调用(避免外部直接创建不完整对象)
private HttpRequestParam(Builder builder) {
// 从 Builder 中获取参数,赋值给当前不可变字段
this.url = builder.url;
this.method = builder.method;
this.headers = builder.headers;
this.params = builder.params;
this.timeout = builder.timeout;
}
// 仅提供 getter 方法,不提供 setter(保证不可变性)
public String getUrl() { return url; }
public String getMethod() { return method; }
public Map<String, String> getHeaders() { return headers; }
public Map<String, String> getParams() { return params; }
public int getTimeout() { return timeout; }
// 重写 toString(),方便打印调试
@Override
public String toString() {
return "HttpRequestParam{" +
"url='" + url + '\'' +
", method='" + method + '\'' +
", headers=" + headers +
", params=" + params +
", timeout=" + timeout +
'}';
}
// 第二步:定义 Builder 内部类(核心构建逻辑)
public static class Builder {
// 1. 必选参数:无默认值,必须由外部设置
private final String url;
private final String method;
// 2. 可选参数:有默认值,外部可按需修改
private Map<String, String> headers = new HashMap<>(); // 默认空请求头
private Map<String, String> params = new HashMap<>(); // 默认空请求参数
private int timeout = 3000; // 默认超时时间 3000ms
/**
* Builder 构造器:强制传入必选参数
* (外部创建 Builder 时,必须先设置 url 和 method,避免遗漏核心参数)
*/
public Builder(String url, String method) {
// 必选参数校验:提前拦截非法值(避免构建出无效对象)
if (url == null || url.trim().isEmpty()) {
throw new IllegalArgumentException("请求地址 url 不能为空!");
}
if (!"GET".equalsIgnoreCase(method) && !"POST".equalsIgnoreCase(method)) {
throw new IllegalArgumentException("仅支持 GET/POST 请求方法!");
}
this.url = url.trim(); // 去空格,保证参数整洁
this.method = method.toUpperCase(); // 统一转为大写(避免大小写混乱)
}
/**
* 可选参数:设置请求头(链式调用)
* @param key 头字段名
* @param value 头字段值
* @return 返回 Builder 自身,支持链式调用
*/
public Builder addHeader(String key, String value) {
if (key != null && value != null) { // 过滤空值
this.headers.put(key, value);
}
return this; // 关键:返回 this,实现链式调用
}
/**
* 可选参数:批量设置请求头
*/
public Builder addHeaders(Map<String, String> headers) {
if (headers != null && !headers.isEmpty()) {
this.headers.putAll(headers);
}
return this;
}
/**
* 可选参数:设置请求参数(链式调用)
*/
public Builder addParam(String key, String value) {
if (key != null && value != null) {
this.params.put(key, value);
}
return this;
}
/**
* 可选参数:批量设置请求参数
*/
public Builder addParams(Map<String, String> params) {
if (params != null && !params.isEmpty()) {
this.params.putAll(params);
}
return this;
}
/**
* 可选参数:设置超时时间
*/
public Builder setTimeout(int timeout) {
if (timeout > 0) { // 校验:超时时间必须为正数
this.timeout = timeout;
}
return this;
}
/**
* 最终构建方法:创建 HttpRequestParam 对象
* @return 不可变的 HttpRequestParam 实例
*/
public HttpRequestParam build() {
// 此处可做最终参数校验(如 headers/params 特殊规则)
return new HttpRequestParam(this); // 调用外部类私有构造器
}
}
}
实际使用过程中,调用:
// 链式调用设置可选参数(addParam/addHeader/setTimeout)
HttpRequestParam fullParam = new HttpRequestParam.Builder(
"https://api.example.com/login", // url
"POST" // method
)
.addParam("username", "zhangsan") // 添加单个请求参数
.addParam("password", "123456")
.addHeader("Content-Type", "application/x-www-form-urlencoded") // 添加请求头
.addHeader("User-Agent", "Android-App/1.0")
.setTimeout(5000) // 覆盖默认超时,设为 5000ms
.build(); // 最终构建
Log.d("BuilderDemo", "完整请求参数:" + fullParam);
// 输出:HttpRequestParam{url='https://api.example.com/login', method='POST',
// headers={Content-Type=application/x-www-form-urlencoded, User-Agent=Android-App/1.0},
// params={username=zhangsan, password=123456}, timeout=5000}
3.核心总结
- 不可变目标类: HttpRequestParam 字段使用final, 无seter, 保证线程安全,避免对象被篡改
- 私有构造器:private HttpRequestParam(Builder builder), 仅允许Builer创建对象,避免外部创建
- Builder内部类: public static class Builder, 封装所有构建逻辑
- 必选参数强制传入+可选参数: Builder 构造器要求url method,避免核心参数遗漏,并可以进行校验
- 链式调用:每个设置方法返回this
您还没有登录,请您登录后发表评论。