构造模式-OkHttp Request的构建

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29078329/article/details/79140387

Builder模式常用于构建复杂对象,经常使用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 的构造函数中。

猜你喜欢

转载自blog.csdn.net/qq_29078329/article/details/79140387