设计模式之builder模式(代码片段)

lijianming180 lijianming180     2023-04-21     417

关键词:

技术图片

参与者

  • 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
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();

调用

1
2
3
4
5
6
7
8
9
10
11
12
13
/** 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分析

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
public RequestCall build()
if (params != null)
url = appendParams(url, params);
return new GetRequest(url, tag, params, headers).build();
// ...
public GetBuilder url(String url)
大专栏  设计模式之Builder模式class="line"> 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);
// ...
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

设计模式之建造者模式(builder)(代码片段)

设计模式非常重要,阅读源码的必不可少的技能。所以接下来的时间对常见的设计模式进行总结和学习。先进行建造者模式的学习。建造者模式使用原理,可以链式调用,当你不需要一些属性的时候,可以不必要传入,而传统的... 查看详情

设计模式之建造者模式(代码片段)

前言建造者模式也是常用的设计模式,Lombok的@Builder就是一个典型的应用。googleguavacache创建cache就只能通过builder方式建造者模式建造者模式有四个角色:1product2抽象builder3实现builder4director建造者模式是的创建对象算法独立,调用... 查看详情

设计模式之builder模式(代码片段)

参与者Builder为创建一个Product对象的各个部件指定抽象接口。ConcreteBuilder实现Builder的接口以构造和装配该产品的各个部件。定义并明确它所创建的表示。提供一个检索产品的接口Director构造一个使用Builder接口的对象。Product表示... 查看详情

23种设计模式之建造者模式(代码片段)

1/**2*作用:3*将复杂物体的构建与表现相分离。4*組成角色:5*1)建造者(Builder):負責定義用來生成實例的接口(API)6*2)具体的建造者(ConcreateBuilder):负责实现Builder角色定义的接口实现类。7*针对不同的业务逻辑,具体化复杂对象的各... 查看详情

设计模式之建造者模式(代码片段)

设计模式之建造者模式(三)  今天来学习建造者模式,好像也有人叫生成器,一个意思.  一 概念  建造者模式:使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创... 查看详情

java设计模式之构建者模式(代码片段)

一、定义:将一个复杂对象分解成多个相对简单的部分,然后根据不同需要分别创建它们,最后构建成该复杂对象。二、角色:建造者模式包含的角色如下:Director:导演类(指挥者),负责安排已有模块... 查看详情

设计模式之建造者模式(代码片段)

 建造者模式:是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 组成: 1、builder:给出一个抽象接口,以规范产品对象的各个组成成分的建造。这个接口规定要实现复杂对象的... 查看详情

java设计模式之建造者模式(代码片段)

转自 JAVA设计模式之建造者模式建造者模式(Builder)的定义将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。Builder模式是一步一步创建一个复杂对象的创建型模式,它允许使用... 查看详情

设计模式之构造器和模板方法(代码片段)

摘要本文是设计模式学习的系列文章之一,主要介绍了常用的Builder(生成器)模式和模板模式。前者属于创建模式,后者属于行为模式。本文会结合具体的代码和实际的应用的案例进行分析。Builder(生成器)的介绍生成器,听名字就... 查看详情

23种设计模式之建造者模式代码实例

建造者模式在实际工作中常常是在测试类造数据的时候使用,继承既定的Builder类之后,新的Builder类可以方便的“建造“各种属性。具体见如下代码。先有默认的既定Builder类:publicinterfaceBuilder{publicvoidbuildPartA();publicvoidbuildPartB();... 查看详情

设计模式之builder模式

  在平时的项目开发中,我们会通过构造方法传参来实例化对象。  但在需要多个参数时,如果继续使用构造方法实例,编写代码会非常麻烦,而且在其他项目成员传参时特别容易出现传参错误的情况,这时我们不妨来使用... 查看详情

javabuilder模式实现(代码片段)

一、借助lombok之@Builder注解User类源码:packagecom.yang.webflux.controller;importlombok.Builder;/***@author:Yang*@date:2017/3/2623:55*@description:*/@BuilderpublicclassUserprivatelongid;privateStringname;privat 查看详情

《设计模式》之建造者模式(builder)

...,如想学习请找下一家。1、简介  是一种对象构建的设计模式,他可以将复杂的建造过程抽象出来,使这个抽象过程的不同实现方法可以构造出不同表现的对象。  优点:建造代码与表示代码分离,有偶遇建造者隐藏了该... 查看详情

设计模式之二:builder模式

设计模式之二:Builder模式目录介绍0.关于Builder模式案例下载1.Builder模式介绍2.Builder模式使用场景3.Builder模式简单案例3.1Builder模式UML图(摘自网络)3.2在《Android源码设计模式》这本书上,介绍经典Builder模式中,包括3.3 Product角... 查看详情

设计模式之建造者模式(创建型)(代码片段)

模式定义建造者模式属于23种设计模式中的创建型模式,可以理解为创建对象的一种很好的方法。所谓建造者模式就是将组件和组件的组件过程分开,然后一步一步建造一个复杂的对象。所以建造者模式又叫生成器模式。建造者... 查看详情

再战设计模式之建造者模式(代码片段)

建造者模式 他的本质主要是:分离了组件的构造(由builder来负责),和装配(由Director负责),从而构造出复杂的对象,这个模式使用于:某个对象构建过程复杂的情况下使用建造模式可以将一个产品的内部表象(internalrepresentation)与... 查看详情

设计模式builder模式(代码片段)

  Builder模式,从这个名字我们可以看出来,这种设计模式就是用于组装具有复杂结构的实例的。  下面还是以一个实例程序来解释这种设计模式,先看实例程序的类图。  这里为了调试方便,只实现其中一个功能TextBuilder... 查看详情

设计模式-----builder模式(代码片段)

前言近日,看到Myabtis中组件中SqlSessionFactory由SqlSessionFactoryBuilder().build()生成时,且采用Builder模式,遂记录学习之。SqlSessionFactorysqlSessionFactory=newSqlSessionFactoryBuilder().build(inputStream);  1、什么是Build 查看详情