我们通过一个例子来引出Builder模式。假设有一个Person类,我们通过该Person类来构建一大批人,这个Person类里有很多属性,最常见的比如name,age,weight,height等等,并且我们允许这些值不被设置,也就是允许为null,该类的定义如下。

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
public class Person {
private String name;
private int age;
private double height;
private double weight; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public double getHeight() {
return height;
} public void setHeight(double height) {
this.height = height;
} public double getWeight() {
return weight;
} public void setWeight(double weight) {
this.weight = weight;
}
}

然后我们为了方便可能会定义一个构造方法。

1
2
3
4
5
6
public Person(String name, int age, double height, double weight) {
this.name = name;
this.age = age;
this.height = height;
this.weight = weight;
}

或许为了方便new对象,你还会定义一个空的构造方法

1
2
public Person() {
}

甚至有时候你很懒,只想传部分参数,你还会定义如下类似的构造方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public Person(String name) {
this.name = name;
} public Person(String name, int age) {
this.name = name;
this.age = age;
} public Person(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}

于是你就可以这样创建各个需要的对象

1
2
3
4
5
Person p1=new Person();
Person p2=new Person("张三");
Person p3=new Person("李四",18);
Person p4=new Person("王五",21,180);
Person p5=new Person("赵六",17,170,65.4);

可以想象一下这样创建的坏处,最直观的就是四个参数的构造函数的最后面的两个参数到底是什么意思,可读性不怎么好,如果不点击看源码,鬼知道哪个是weight哪个是height。还有一个问题就是当有很多参数时,编写这个构造函数就会显得异常麻烦,这时候如果换一个角度,试试Builder模式,你会发现代码的可读性一下子就上去了。

我们给Person增加一个静态内部类Builder类,并修改Person类的构造函数,代码如下。

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
64
65
66
67
68
69
70
71
72
public class Person {
private String name;
private int age;
private double height;
private double weight; privatePerson(Builder builder) {
this.name=builder.name;
this.age=builder.age;
this.height=builder.height;
this.weight=builder.weight;
}
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public double getHeight() {
return height;
} public void setHeight(double height) {
this.height = height;
} public double getWeight() {
return weight;
} public void setWeight(double weight) {
this.weight = weight;
} static class Builder{
private String name;
private int age;
private double height;
private double weight;
public Builder name(String name){
this.name=name;
return this;
}
public Builder age(int age){
this.age=age;
return this;
}
public Builder height(double height){
this.height=height;
return this;
} public Builder weight(double weight){
this.weight=weight;
return this;
} public Person build(){
return new Person(this);
}
}
}

从上面的代码中我们可以看到,我们在Builder类里定义了一份与Person类一模一样的变量,通过一系列的成员函数进行设置属性值,但是返回值都是this,也就是都是Builder对象,最后提供了一个build函数用于创建Person对象,返回的是Person对象,对应的构造函数在Person类中进行定义,也就是构造函数的入参是Builder对象,然后依次对自己的成员变量进行赋值,对应的值都是Builder对象中的值。此外Builder类中的成员函数返回Builder对象自身的另一个作用就是让它支持链式调用,使代码可读性大大增强。

于是我们就可以这样创建Person类。

1
2
3
4
5
6
7
Person.Builder builder=new Person.Builder();
Person person=builder
.name("张三")
.age(18)
.height(178.5)
.weight(67.4)
.build();

有没有觉得创建过程一下子就变得那么清晰了。对应的值是什么属性一目了然,可读性大大增强。

其实在Android中, Builder模式也是被大量的运用。比如常见的对话框的创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
AlertDialog.Builder builder=new AlertDialog.Builder(this);
AlertDialog dialog=builder.setTitle("标题")
.setIcon(android.R.drawable.ic_dialog_alert)
.setView(R.layout.myview)
.setPositiveButton(R.string.positive, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) { }
})
.setNegativeButton(R.string.negative, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) { }
})
.create();
dialog.show();

android 开发设计模式---Builder模式的更多相关文章

  1. android 开发设计模式---Strategy模式

    假设我们要出去旅游,而去旅游出行的方式有很多,有步行,有坐火车,有坐飞机等等.而如果不使用任何模式,我们的代码可能就是这样子的. 12345678910111213141516171819202122 ...

  2. 设计模式-----Builder模式

    前言 近日,看到Myabtis中组件中SqlSessionFactory由SqlSessionFactoryBuilder().build()生成时,且采用Builder模式,遂记录学习之. SqlS ...

  3. java设计模式--Builder模式

    一.Builder模式 二.使用例子 三.Spring中的Builder模式 Builder模式,构建者.构造者模式,在<图解设计模式>中归为 生成实例 一栏,该模式用于组装具有复杂结构的 ...

  4. java的设计模式 - Builder模式

    Builder 模式的目的? 构造对象的方式过于复杂,不如将之抽离出来.比如,构造器参数过多 这样说也有点抽象,举个例子吧. 举个例子 比如 非常热门的消息队列RabbitMQ 的 AMQP.Basi ...

  5. Android开发设计模式之——单例模式关于线程不安全问题处理

    单例模式是设计模式中最常见也最简单的一种设计模式,保证了在程序中只有一个实例存在并且能全局的访问到.比如在Android实际APP 开发中用到的 账号信息对象管理, 数据库对象(SQLiteOpenH ...

  6. Android开发之模板模式初探

    模板模式我认为在Android的开发中是最长用到的,基本是随处可见的,认识该模式,有助于我们对Android的源代码及框架有一个更深层次的认识.那什么是模板模式呢,模板模式就是定义一个基本框架,将当中 ...

  7. android 开发AlertDialog.builder对话框的实现

    AndroidAPI提供了Dialog对话框控件,但google明确指出不建议开发者只是使用Dialog来创建对话框,而应该自定义对话框或者使用API中提供的Dialog的子类,如AlertDialo ...

  8. Android开发——Activity启动模式详解

    1. Activity的启动模式 本文原创,转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52054893 1.1 Standard标 ...

  9. 设计模式-Builder模式(创建型模式)

    //以下代码来源: 设计模式精解-GoF 23种设计模式解析附C++实现源码 //Product.h #pragma once class Product { public: Product(); ~ ...

随机推荐

  1. LeetCode(21. 合并两个有序链表)

    问题描述 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1->3->4 输出:1->1-& ...

  2. 编程菜鸟的日记-初学尝试编程-C++ Primer Plus 第5章编程练习3

    #include <iostream>using namespace std;int main(){ double count=0; long double cleo=100; long ...

  3. easyui commobox省市区县三级联动

    1.前端代码 <div class="col-6 f-group"> <label class="col-4 left_red"> 省名 ...

  4. ajax 传递中文字符参数 问题

    使用ajax 传递中文字符串时, 服务端会接收不到预期的 中文字符. 此时,需要对 js中的中文字符参数进行 编码,  到达服务端后, 再为其解码 即可. 前端: var url = '....'; ...

  5. python +ps 三方面库整理

    -------------------------------------------端口进程相关------------------------------------------------cp ...

  6. mysql中各种日期数据类型及其所占用的空间

    DATETIME,8字节: DATE,3字节: TIMESTAMP,4字节: YEAR,1字节: TIME,3字节:

  7. spark-sql分组去重总数统计uv

    SparkConf sparkConf = new SparkConf(); sparkConf .setAppName("Internal_Func") .setMaster(& ...

  8. nodejs技术升阶思路

    经历一两年的node后端开发,熟悉了node原生api.常用包.数据库操作语句.一两个框架等,技术会达到一个瓶颈.如果没有足够的动力去深入,很容易老死在这个瓶颈上. 下面总结一下,提升点和方向: 站在 ...

  9. Mysql5.8解压版安装问题:TCP/IP, --shared-memory, or --named-pipe should be configured on NT OS

    问题描述: cmd显示如下: .err文件显示: [ERROR] [MY-010131] [Server] TCP/IP, --shared-memory, or --named-pipe shoul ...

  10. TestNG Suite 运行出现中文乱码如何解决

    场景: 用TestNG框架运行测试类,控制台视图输出出现中文乱码. 解决方案: 1.eclipse属性>workspace>other>utf-8 2.修改eclipse.ini 文 ...