了解了单例模式,接下来介绍另一个常见的模式——Builder模式。

那么什么是Builder模式呢。通过搜索,会发现大部分网上的定义都是

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示

但是看完这个定义,依然不知道什么是Builder设计模式。不要过度在意其定义,定义往往是比较抽象的,学习它最好的例子就是通过样例代码。

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

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;
}
}

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

public Person(String name, int age, double height, double weight) {
this.name = name;
this.age = age;
this.height = height;
this.weight = weight;
}

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

public Person() {
}

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

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;
}

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

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类的构造函数,代码如下。

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类。

Person.Builder builder=new Person.Builder();
Person person=builder
.name("张三")
.age(18)
.height(178.5)
.weight(67.4)
.build();

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

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

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

其实在java中有两个常见的类也是Builder模式,那就是StringBuilder和StringBuffer,只不过其实现过程简化了一点罢了。

我们再找找Builder模式在各个框架中的应用。

如Gson中的GsonBuilder,这里只贴出其Builder的使用方法。

GsonBuilder builder=new GsonBuilder();
Gson gson=builder.setPrettyPrinting()
.disableHtmlEscaping()
.generateNonExecutableJson()
.serializeNulls()
.create();

可见各大框架中大量的运用了Builder模式。最后总结一下

  • 定义一个静态内部类Builder,内部的成员变量和外部类一样
  • Builder类通过一系列的方法用于成员变量的赋值,并返回当前对象本身(this)
  • Builder类提供一个build方法或者create方法用于创建对应的外部类,该方法内部调用了外部类的一个私有构造函数,该构造函数的参数就是内部类Builder
  • 外部类提供一个私有构造函数供内部类调用,在该构造函数中完成成员变量的赋值,取值为Builder对象中对应的值

Android开发中常见的设计模式(二)——Builder模式的更多相关文章

  1. Android开发中常见的设计模式 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  2. Android开发中无处不在的设计模式——动态代理模式

    继续更新设计模式系列.写这个模式的主要原因是近期看到了动态代理的代码. 先来回想一下前5个模式: - Android开发中无处不在的设计模式--单例模式 - Android开发中无处不在的设计模式-- ...

  3. Android开发中常见的设计模式

    对于开发人员来说,设计模式有时候就是一道坎,但是设计模式又非常有用,过了这道坎,它可以让你水平提高一个档次.而在android开发中,必要的了解一些设计模式又是非常有必要的.对于想系统的学习设计模式的 ...

  4. Android开发中常见的设计模式(一)——单例模式

    首先了解一些单例模式的概念. 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 这样做有以下几个优点 对于那些比较耗内存的类,只实例化一次可以大大提高性能,尤其是在移动开发中. 保持 ...

  5. Android开发中常见的设计模式(四)——策略模式

    策略模式定义了一些列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变换. 假设我们要出去旅游,而去旅游出行的方式有很多,有步行,有坐火车,有坐飞机等等 ...

  6. Android开发中常见的设计模式(三)——观察者模式

    先看下这个模式的定义. 定义对象间的一种一对多的依赖关系,当一个对象的状态发送改变时,所有依赖于它的对象都能得到通知并被自动更新 先来讲几个情景. 情景1:有一种短信服务,比如天气预报服务,一旦你订阅 ...

  7. Android开发中常用的设计模式

    首先需要说明的是,这篇博文灵感来自于 http://www.cnblogs.com/qianxudetianxia/archive/2011/07/29/2121547.html ,在这里,博主已经很 ...

  8. Android 开发中常见的注意点

    这里总结了Android开发中常用的注意点.只有总结,没有展开举例讲解,展开的话,一个点都可以写一篇文章了..... 这类问题都一定不要犯. 重要的事情说三遍!!! 说三遍!!! 遍!!! 资源 不允 ...

  9. iOS 开发中常见的设计模式

    最近有小伙伴问到在iOS开发中的几种设计模式,这里摘录一下别人的总结(因为已经感觉总结得差不多了,适用的可以阅读一下) 首先是开发中的23中设计模式分为三大类:1.创建型 2.结构型 3.行为型 (i ...

随机推荐

  1. wcf 数值类型赋值不能的问题解决

    客户端给对象int类型赋值,服务端收到值为0 网上给出的方案 1.数值型字段+isrequired属性.能解决问题,但没有说明原因.数值型默认不赋值,不科学. 2.emitdefaultvalue.没 ...

  2. Python 简说 list,tuple,dict,set

    python 是按缩进来识别代码块的 . 缩进请严格按照Python的习惯写法:4个空格,不要使用Tab,更不要混合Tab和空格,否则很容易造成因为缩进引起的语法错误. list  有序集合  访问不 ...

  3. 实现java随机数Random的几招

    一,在java.util这个包里面提供了一个Random的类,我们可以新建一个Random的对象来产生随机数,可以产生随机整数.随机float.随机double,随机long,这个也是我们经常用的一个 ...

  4. 微信h5支付demo微信H5支付demo非微信浏览器支付demo微信wap支付

    服务项目 新手技术咨询 企业技术咨询 定制开发 服务说明 QQ有问必答 QQ.微信.电话 微信开发.php开发,网站开发,系统定制,小程序开发 价格说明 200元/月 1000/月 商议       ...

  5. 黄聪:微信公众平台开发OAuth2.0网页授权(转)

    微信公众平台开发 OAuth2.0网页授权认证 网页授权获取用户基本信息 作者:方倍工作室 微信公众平台最近新推出微信认证,认证后可以获得高级接口权限,其中一个是OAuth2.0网页授权,很多朋友在使 ...

  6. 【VSCode】Windows下VSCode编译调试c/c++【更新】

    便携版已更新,点此获取便携版 用于cpptools插件的配置文件更新 更新的launch.json // Available variables which can be used inside of ...

  7. Selenium2+python自动化43-判断title(title_is)

    From: https://www.cnblogs.com/yoyoketang/p/6539117.html 前言 获取页面title的方法可以直接用driver.title获取到,然后也可以把获取 ...

  8. 图像处理PILLOW的使用

    1.安装 pip install Pillow 2.使用 1)图片缩放 from PIL import Imageim = Image.open('dog.jpg') w,h = im.size #获 ...

  9. [翻译]Restful Web服务模型

    最近我一直在阅读“Rest实践”的草稿:一本几位同事一直在努力编写的书. 他们的目的是解释如何使用Restful Web服务来处理企业面临的许多集成问题. 这本书的核心在于这样一种观点,Web以一个有 ...

  10. PAT 乙级 1049 数列的片段和(20) C++版

    1049. 数列的片段和(20) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CAO, Peng 给定一个正数数列,我们可以从中截 ...