参与者
Builder 为创建一个Product对象的各个部件指定抽象接口。
ConcreteBuilder 实现Builder的接口以构造和装配该产品的各个部件。 定义并明确它所创建的表示。 提供一个检索产品的接口
Director 构造一个使用Builder接口的对象。
Product 表示被构造的复杂对象。ConcreateBuilder创建该产品的内部表示并定义它的装配过程。 包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
使用场景 产品复杂,且它允许使用者不必知道内部构建细节的情况下使用。注意: 现实开发过程中,Director角色经常会被省略。直接使用Builder来进对象的组装,这个Builder通常为链式调用,它的关键点是每个方法都返回自身 - return this,这使得set方法可以链式调用,代码如下:Test test = new Test.Builder().setA("A").setB("B").create();
Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 class Pizza { private String dough = "" ; private String sauce = "" ; private String topping = "" ; public void setDough (String dough ) { this .dough = dough; } public void setSauce (String sauce ) { this .sauce = sauce; } public void setTopping (String topping ) { this .topping = topping; } } '' '' abstract class PizzaBuilder { protected Pizza pizza; public Pizza getPizza () { return pizza; } public void createNewPizzaProduct () { pizza = new Pizza(); } public abstract void buildDough () ; public abstract void buildSauce () ; public abstract void buildTopping () ; } class HawaiianPizzaBuilder extends PizzaBuilder { public void buildDough () { pizza.setDough("cross" ); } public void buildSauce () { pizza.setSauce("mild" ); } public void buildTopping () { pizza.setTopping("ham+pineapple" ); } } class SpicyPizzaBuilder extends PizzaBuilder { public void buildDough () { pizza.setDough("pan baked" ); } public void buildSauce () { pizza.setSauce("hot" ); } public void buildTopping () { pizza.setTopping("pepperoni+salami" ); } } '' '' class Waiter { private PizzaBuilder pizzaBuilder; public void setPizzaBuilder (PizzaBuilder pb ) { pizzaBuilder = pb; } public Pizza getPizza () { return pizzaBuilder.getPizza(); } public void constructPizza () { pizzaBuilder.createNewPizzaProduct(); pizzaBuilder.buildDough(); pizzaBuilder.buildSauce(); pizzaBuilder.buildTopping(); } }
调用 1 2 3 4 5 6 7 8 9 10 11 12 13 class BuilderExample { public static void main(String [] args) { Waiter waiter = new Waiter (); PizzaBuilder hawaiian_pizzabuilder = new HawaiianPizzaBuilder (); PizzaBuilder spicy_pizzabuilder = new SpicyPizzaBuilder (); waiter.setPizzaBuilder ( hawaiian_pizzabuilder ); waiter.constructPizza(); Pizza pizza = waiter.getPizza(); } }
实际场景举一例 okhttputils 请求Get分析
1 2 3 4 5 6 String url = "http://www.csdn.net/" ;OkHttpUtils .get () .url(url) .build() .execute(new MyStringCallback ());
首先看到这里有个build(),估计就是建造模式了,摸进去一看,没有错。
.get()
进去一看,果然不假
1 2 3 4 public static GetBuilder get (){ return new GetBuilder(); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class GetBuilder extends OkHttpRequestBuilder { @Override public RequestCall build() { if (params != null ) { url = appendParams(url, params); } return new GetRequest (url, tag, params, headers).build(); } @Override public GetBuilder url(String url) { this .url = url; return this ; } }
这里设定了url,且看到已经看到了build()方法,基本和最初的判定一致,是Builder模式,但这跟Okhttp用法还是有差距,继续跟进,发现最初.get()
的GetBuilder直接将设置的数据全部扔进OkHttpRequest了 - 这、、、
1 2 3 4 5 6 7 8 9 10 11 12 public class GetRequest extends OkHttpRequest { public GetRequest (String url, Object tag, Map <String , String > params, Map <String , String > headers) { super (url, tag, params, headers); } @Override protected Request buildRequest (Request.Builder builder, RequestBody requestBody ) { return builder.get ().build (); }
尼玛,坑啊,build()没有?继续
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 public abstract class OkHttpRequest { protected String url; protected Object tag; protected Map <String , String > params; protected Map <String , String > headers; protected Request .Builder builder = new Request .Builder (); protected OkHttpRequest (String url, Object tag, Map <String , String > params, Map <String , String > headers) { this .url = url; this .tag = tag; this .params = params; this .headers = headers; if (url == null ) { Exceptions .illegalArgument ("url can not be null." ); } } protected abstract Request buildRequest (Request .Builder builder, RequestBody requestBody); public RequestCall build ( ) { return new RequestCall (this ); } public Request generateRequest (Callback callback ) { RequestBody requestBody = wrapRequestBody (buildRequestBody (), callback); prepareBuilder (); return buildRequest (builder, requestBody); } private void prepareBuilder ( ) { builder.url (url).tag (tag); appendHeaders (); } }
终于看到我辛苦设置的参数都在这里了,返回了RequestCall,也看到眼熟的Requset.Builder ,但目前还是没有看到谁调用了它 ,看来还得继续深入RequestCall
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 public class RequestCall { private OkHttpRequest okHttpRequest; private Request request; private Call call; private OkHttpClient clone; public RequestCall (OkHttpRequest request) { this .okHttpRequest = request; } public Call generateCall (Callback callback) { request = generateRequest(callback); if (readTimeOut > 0 || writeTimeOut > 0 || connTimeOut > 0 ) { readTimeOut = readTimeOut > 0 ? readTimeOut : OkHttpUtils.DEFAULT_MILLISECONDS; writeTimeOut = writeTimeOut > 0 ? writeTimeOut : OkHttpUtils.DEFAULT_MILLISECONDS; connTimeOut = connTimeOut > 0 ? connTimeOut : OkHttpUtils.DEFAULT_MILLISECONDS; clone = OkHttpUtils.getInstance().getOkHttpClient().newBuilder() .readTimeout(readTimeOut, TimeUnit.MILLISECONDS) .writeTimeout(writeTimeOut, TimeUnit.MILLISECONDS) .connectTimeout(connTimeOut, TimeUnit.MILLISECONDS) .build(); call = clone.newCall(request); } else { call = OkHttpUtils.getInstance().getOkHttpClient().newCall(request); } return call; } private Request generateRequest (Callback callback) { return okHttpRequest.generateRequest (callback) ; } public void execute (Callback callback) { generateCall(callback); if (callback != null ) { callback.onBefore(request); } OkHttpUtils.getInstance().execute(this , callback); } public Response execute () throws IOException { generateCall(null ); return call.execute () ; } }
在这里可以看到Client,request,call了,OkHttpUtils.getInstance().getOkHttpClient()
、request = generateRequest(callback)
、generateCall
,且最后还执行了execute
- call.execute()
总结一下这个开源
OkHttpUtils.get().url(url).build()
得到了RequestCall,Builder模式呈现
化繁为简,网络请求不需要自己再封装就能够方便的使用
设置下url,就有了OkHttp的Client,request,call和一系繁锁设置,直接调用execute()
execute(Callback callback)方法会回调到OkHttpUtils,用主线程Handler更新请求
将OkHttpClient放进了OkHttpUtils;将Request转变成GetRequest;将Request.Builder替换成GetBuilder;将Call替换成RequestCall