设计模式之Builder模式
来源:互联网 发布:windows ble蓝牙开发 编辑:程序博客网 时间:2024/04/28 07:00
参与者
- 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
/** "Product" */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 Builder" */''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();}/** "ConcreteBuilder" */class HawaiianPizzaBuilder extends PizzaBuilder { public void buildDough() { pizza.setDough("cross"); } public void buildSauce() { pizza.setSauce("mild"); } public void buildTopping() { pizza.setTopping("ham+pineapple"); }}/** "ConcreteBuilder" */class SpicyPizzaBuilder extends PizzaBuilder { public void buildDough() { pizza.setDough("pan baked"); } public void buildSauce() { pizza.setSauce("hot"); } public void buildTopping() { pizza.setTopping("pepperoni+salami"); }}''/** "Director" */''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(); }}
调用
/** A customer ordering a pizza. */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分析
String url = "http://www.csdn.net/";OkHttpUtils .get() .url(url) .build() .execute(new MyStringCallback());
首先看到这里有个build(),估计就是建造模式了,摸进去一看,没有错。
.get()
进去一看,果然不假
public static GetBuilder get(){ return new GetBuilder();}
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了 - 这、、、
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()没有?继续
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
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
0 0
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之Builder
- 设计模式之 builder
- 设计模式之Builder
- 设计模式之builder
- hdu 4417 划分树
- HDOJ 2079 选课时间(题目已修改,注意读题)(母函数模板题)
- VC6.0下PHP扩展开发详细教程
- 用Intent.ACTION_SEND进行分享
- 吐槽Win7 x64资源管理器
- 设计模式之Builder模式
- 音乐播放器中的跳动的平衡器
- Java 如何将字符串信息直接写保存到文本文件
- 数据结构实践——迷宫问题之图深度优先遍历解法
- squeeze函数编写
- 字符串转化为十六进制
- how to add external library in qt under ubuntu
- LeetCode_37 Sudoku Solver
- 论----计算机程序智能化