构建者builder模式

本文介绍构建者模式在创建复杂对象时的优势,通过模仿okhttp框架创建request对象的实例,展示了如何使用构建者模式提高代码的可读性和安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  遇到多个构造器参数时,我们可以考虑使用构建器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代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值