遇到多个构造器参数时,我们可以考虑使用构建器Builder模式,相比于重叠构造器模式(定义多个重载的构造函数),JavaBeans模式(通过set方法挨个构造),Builder构建者模式实现的方式更加优雅,对象更利于使用,在保证安全性的同时又兼顾了可读性。
一些著名的框架,比如okhttp, retrofit,安卓中各种原生的组件,比如dialog等随处可见Builder构建者模式。
接下来模仿okhttp用构建者模式来创建一个request对象:
/**
* 用构建者builder模式模拟okhttp来创建request对象
* Created by wujie on 2018/10/17.
*/
public class Request {
private final HttpUrl url;
private final String method;
private final Headers headers;
private final RequestBody body;
private Request(Builder builder) {
url = builder.url;
method = builder.method;
headers = builder.headers.build();
body = builder.body;
}
public static final class Builder {
private HttpUrl url;
private String method;
private Headers.Builder headers;
private RequestBody body;
public Builder() {
this.method = "GET";
this.headers = new Headers.Builder();
}
public Builder url(String url) {
if (url == null) throw new NullPointerException("url == null");
// websocket URLs with HTTP URLs.
if (url.regionMatches(true, 0, "ws:", 0, 3)) {
url = "http:" + url.substring(3);
} else if (url.regionMatches(true, 0, "wss:", 0, 4)) {
url = "https:" + url.substring(4);
}
HttpUrl parsed = HttpUrl.parse(url);
if (parsed == null) throw new IllegalArgumentException("unexpected url: " + url);
return url(parsed);
}
public Builder url(HttpUrl url) {
if (url == null) throw new NullPointerException("url == null");
this.url = url;
return this;
}
public Builder method(String method, RequestBody body) {
if (method == null) throw new NullPointerException("method == null");
if (method.length() == 0) throw new IllegalArgumentException("method.length() == 0");
if (body != null && !HttpMethod.permitsRequestBody(method)) {
throw new IllegalArgumentException("method " + method + " must not have a request body.");
}
if (body == null && HttpMethod.requiresRequestBody(method)) {
throw new IllegalArgumentException("method " + method + " must have a request body.");
}
this.method = method;
this.body = body;
return this;
}
public Builder addHeader(String name, String value) {
headers.add(name, value);
return this;
}
public Builder get() {
return method("GET", null);
}
public Builder head() {
return method("HEAD", null);
}
public Builder post(RequestBody body) {
return method("POST", body);
}
public Builder delete(RequestBody body) {
return method("DELETE", body);
}
public Builder delete() {
return delete(Util.EMPTY_REQUEST);
}
public Builder put(RequestBody body) {
return method("PUT", body);
}
public Builder body(RequestBody body) {
this.body = body;
return this;
}
public Request build() {
return new Request(this);
}
}
}
链式调用也很方便:
public static void main(String[] args) {
//链式调用
Request request = new Request.Builder()
.url(HttpUrl.parse("https://blog.youkuaiyun.com/baiyicanggou_wujie"))
.addHeader("appid", "123456")
.addHeader("appsercet", "123456")
.post("填写你要post的requestBody")
.build();
}
小技巧:idea可以下载innerBuilder或者lombok的@builder注解生成一般的builder代码。