构造模式-OkHttp Request的构建
2018-01-23 16:23
211 查看
Builder模式常用于构建复杂对象,经常使用Builder模式来代替多参数的构造函数,我们常常需要编写这样的实现类,这个类拥有多个构造函数:
这样一系列的构造函数主要目的就是给客户提供更多的调用选择,以处理不同的构造请求,类的作者不得不书写多种参数组合的构造函数,而且其中还需要设置默认参数值,这是一个需要细心而又枯燥的工作,而且如果属性过多的话会让构造函数十分臃肿,使用Builder模式可以通过一个代理来完成对象的构建过程。将上面的多个构造函数改成builder模式如下:
public class User {
private final int userId;
private final String userName;
private final int age;
private final boolean isMale;
public int getUserId() {
return userId;
}
public String getUserName() {
return userName;
}
public int getAge() {
return age;
}
public boolean isMale() {
return isMale;
}
public static class Builder {
private int userId;
private String userName;
private int age;
private boolean isMale;
//必传的参数在构造方法中设置
public Builder(int userId) {
this.userId = userId;
}
public Builder userName(String userName) {
this.userName = userName;
return this;
}
public Builder age(int age) {
this.age = age;
return this;
}
public Builder isMale(boolean isMale) {
this.isMale = isMale;
return this;
}
public User build() {
return new User(this);
}
}
private User(Builder builder) {
userId = builder.userId;
userName = builder.userName;
age = builder.age;
isMale = builder.isMale;
}
}
使用:
Builder是User的静态内部类,并且Builder中的属性和User中的属性一致,User所有的属性值设置都在Builder中,User中只有获取属性的方法。
OkHttp中的Request的构造也是采用的builder模式,如下:
使用Builder构造一个Request对象:
Builder模式创建的对象,在调用build()方法之前是不会创建Request对象的,所有的属性设置都必须在build()方法之前,而且创建了Request对象后就不可以更改其属性了,这就保证了对象状态的唯一性,而且代码的可读性也提高了;如果有些参数是必填的,可以加到Builder 的构造函数中。
public class User { private int userId; private String userName; private int age; private boolean isMale; public User(int userId) { this(userId, null, 0, true); } public User(int userId, String userName) { this(userId, userName, 0, true); } public User(int userId, String userName, int age) { this(userId, userName, age, true); } public User(int userId, String userName, int age, boolean isMale) { this.userId = userId; this.userName = userName; this.age = age; this.isMale = isMale; } }
这样一系列的构造函数主要目的就是给客户提供更多的调用选择,以处理不同的构造请求,类的作者不得不书写多种参数组合的构造函数,而且其中还需要设置默认参数值,这是一个需要细心而又枯燥的工作,而且如果属性过多的话会让构造函数十分臃肿,使用Builder模式可以通过一个代理来完成对象的构建过程。将上面的多个构造函数改成builder模式如下:
public class User {
private final int userId;
private final String userName;
private final int age;
private final boolean isMale;
public int getUserId() {
return userId;
}
public String getUserName() {
return userName;
}
public int getAge() {
return age;
}
public boolean isMale() {
return isMale;
}
public static class Builder {
private int userId;
private String userName;
private int age;
private boolean isMale;
//必传的参数在构造方法中设置
public Builder(int userId) {
this.userId = userId;
}
public Builder userName(String userName) {
this.userName = userName;
return this;
}
public Builder age(int age) {
this.age = age;
return this;
}
public Builder isMale(boolean isMale) {
this.isMale = isMale;
return this;
}
public User build() {
return new User(this);
}
}
private User(Builder builder) {
userId = builder.userId;
userName = builder.userName;
age = builder.age;
isMale = builder.isMale;
}
}
使用:
User user = new Builder(111).userName("zhangsan").age(26).isMale(true).build();
Builder是User的静态内部类,并且Builder中的属性和User中的属性一致,User所有的属性值设置都在Builder中,User中只有获取属性的方法。
OkHttp中的Request的构造也是采用的builder模式,如下:
public final class Request { final HttpUrl url; final String method; final Headers headers; final RequestBody body; final Object tag; Request(Builder builder) { this.url = builder.url; this.method = builder.method; this.headers = builder.headers.build(); this.body = builder.body; this.tag = builder.tag != null ? builder.tag : this; } public HttpUrl url() { return url; } public String method() { return method; } public Headers headers() { return headers; } public String header(String name) { return headers.get(name); } public List<String> headers(String name) { return headers.values(name); } public RequestBody body() { return body; } public Object tag() { return tag; } public Builder newBuilder() { return new Builder(this); } public CacheControl cacheControl() { CacheControl result = cacheControl; return result != null ? result : (cacheControl = CacheControl.parse(headers)); } public boolean isHttps() { return url.isHttps(); } public static class Builder { HttpUrl url; String method; Headers.Builder headers; RequestBody body; Object tag; public Builder() { this.method = "GET"; this.headers = new Headers.Builder(); } Builder(Request request) { this.url = request.url; this.method = request.method; this.body = request.body; this.tag = request.tag; this.headers = request.headers.newBuilder(); } public Builder url(HttpUrl url) { if (url == null) throw new NullPointerException("url == null"); this.url = url; return this; } public Builder url(String url) { if (url == null) throw new NullPointerException("url == null"); // Silently replace web socket 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(URL url) { if (url == null) throw new NullPointerException("url == null"); HttpUrl parsed = HttpUrl.get(url); if (parsed == null) throw new IllegalArgumentException("unexpected url: " + url); return url(parsed); } public Builder header(String name, String value) { headers.set(name, value); return this; } public Builder addHeader(String name, String value) { headers.add(name, value); return this; } public Builder removeHeader(String name) { headers.removeAll(name); return this; } public Builder headers(Headers headers) { this.headers = headers.newBuilder(); return this; } public Builder cacheControl(CacheControl cacheControl) { String value = cacheControl.toString(); if (value.isEmpty()) return removeHeader("Cache-Control"); return header("Cache-Control", value); } 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 patch(RequestBody body) { return method("PATCH", body); } 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 tag(Object tag) { this.tag = tag; return this; } /* * Request 对象创建器,想得到一个Request 对象必须使用build 方法, * 在方法中增加对Builder参数的验证,并以异常的形式告诉给开发人员。 */ public Request build() { /** * 比如下面判断如果 url 是null的话就会抛出异常 */ if (url == null) throw new IllegalStateException("url == null"); return new Request(this); } } }
使用Builder构造一个Request对象:
Request request = new Request.Builder() .url("http://www.youtube.com") .addHeader("header","header") .put("RequestBody") .build();
Builder模式创建的对象,在调用build()方法之前是不会创建Request对象的,所有的属性设置都必须在build()方法之前,而且创建了Request对象后就不可以更改其属性了,这就保证了对象状态的唯一性,而且代码的可读性也提高了;如果有些参数是必填的,可以加到Builder 的构造函数中。
相关文章推荐
- 从Okhttp的建造者模式开始讲
- Mvp设计模式实现okHttpClient请求展示在RecycleView
- 从Okhttp的建造者模式开始讲
- 构建高性能的 HTTP 服务器 (二)--NIO 模式的HTTP服务器
- 从Okhttp的建造者模式开始讲
- Retrofit,Okhttp对每个Request统一动态添加header和参数
- 通过HttpServletRequestWrapper(装饰模式的应用)增强HttpServletRequest的功能
- Comet4J(Comet for Java)是一个纯粹基于AJAX(XMLHTTPRequest)的服务器推送框架,消息以JSON方式传递,具备长轮询、长连接、自动选择三种工作模式。
- 从Okhttp的建造者模式开始讲
- AJAX工作模式、XMLHttpRequest对象、运行流程
- 23种设计模式之——责任链模式(okhttp 拦截器)
- HttpSendRequest的header的构造
- Linux下以C构建WEB服务并响应XHR(XMLHttpRequest)请求
- 从Okhttp的建造者模式开始讲
- Linux下以C构建WEB服务并响应XHR(XMLHttpRequest)请求
- Spring的构造请求类 SimpleClientHttpRequestFactory
- HttpSendRequest向服务端发送数据,构造请求http头
- kotlin for android----------MVP模式下(OKHttp和 Retrofit+RxJava)网络请求的两种实现方式
- Builder模式演义(2)——OkHttp源码中的Builder模式
- 从Okhttp的建造者模式开始讲