Java设计中的Builder模式的介绍


Posted in Javascript onMarch 22, 2018

概述

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

使用场景

  • 相同的方法,不同的执行顺序,产生不同的事件结果
  • 多个部件或零件,都可以装配到一个对象中,但产生的运行结果又不相同时
  • 产品类非常复杂,或者产品类中的调用顺序不同产生不同的作用
  • 当初始化一个对象特别复杂,如参数多,且很多参数都具有默认值时

下面从一个Person例子进行分析重叠构造器模式、JavaBeans模式、Builder模式的使用。Person类有两个必要参数(id和name),有5个可选参数(age,sex,phone,address和desc)

重叠构造器模式

在这种模式下,你提供第一个只有必要参数的构造器,第二个构造器有一个可选参数,第三个有两个可选参数,依此类推,最后一个构造器包含所有的可选参数。下面看看其编程实现:

/ * 使用重叠构造器模式
 */
public class Person {
 //必要参数
 private final int id;
 private final String name;
 //可选参数
 private final int age;
 private final String sex;
 private final String phone;
 private final String address;
 private final String desc;
 public Person(int id, String name) {
 this(id, name, 0);
 }
 public Person(int id, String name, int age) {
 this(id, name, age, "");
 }
 public Person(int id, String name, int age, String sex) {
 this(id, name, age, sex, "");
 }
 public Person(int id, String name, int age, String sex, String phone) {
 this(id, name, age, sex, phone, "");
 }
 public Person(int id, String name, int age, String sex, String phone, String address) {
 this(id, name, age, sex, phone, address, "");
 }
 public Person(int id, String name, int age, String sex, String phone, String address, String desc) {
 this.id = id;
 this.name = name;
 this.age = age;
 this.sex = sex;
 this.phone = phone;
 this.address = address;
 this.desc = desc;
 }
}

从上面的代码中,当你想要创建实例的时候,就利用参数列表最短的构造器,但该列表中包含了要设置的所有参数:

Person person = new Persion(1, "李四", 20, "男", "18800000000", "China", "测试使用重叠构造器模式");

重叠构造器可行,但是当有许多参数的时候,创建使用代码会很难写,并且较难以阅读

JavaBeans模式

采用Javabean 的写法,写一堆属性的setter方法,通过生成对象,让后调用setter方法给属性赋值。

/ * 使用JavaBeans模式
 */
public class Person {
 //必要参数
 private int id;
 private String name;
 //可选参数
 private int age;
 private String sex;
 private String phone;
 private String address;
 private String desc;
 public void setId(int id) {
 this.id = id;
 }
 public void setName(String name) {
 this.name = name;
 }
 public void setAge(int age) {
 this.age = age;
 }
 public void setSex(String sex) {
 this.sex = sex;
 }
 public void setPhone(String phone) {
 this.phone = phone;
 }
 public void setAddress(String address) {
 this.address = address;
 }
 public void setDesc(String desc) {
 this.desc = desc;
 }

这种模式弥补了重叠构造器模式的不足。创建实例很容易,这样产生的代码读起来也很容易:

Person person = new Person();
person.setId(1);
person.setName("李四");
person.setAge(20);
person.setSex("男");
person.setPhone("18800000000");
person.setAddress("China");
person.setDesc("测试使用JavaBeans模式");

JavaBeans模式因为构造过程被分到了几个调用中,在构造过程中JavaBean可能处于不一致的状态。类无法仅仅通过检验构造器参数的有效性来保证一致性。

Builder模式

Builder模式既能保证像重叠构造器那样的安全,也能实现JavaBean模式那样的可读性。

/**
 * 使用Builder模式
 */
public class Person {
 //必要参数
 private final int id;
 private final String name;
 //可选参数
 private final int age;
 private final String sex;
 private final String phone;
 private final String address;
 private final String desc;
 private Person(Builder builder) {
 this.id = builder.id;
 this.name = builder.name;
 this.age = builder.age;
 this.sex = builder.sex;
 this.phone = builder.phone;
 this.address = builder.address;
 this.desc = builder.desc;
 }
 public static class Builder {
 //必要参数
 private final int id;
 private final String name;
 //可选参数
 private int age;
 private String sex;
 private String phone;
 private String address;
 private String desc;
 public Builder(int id, String name) {
  this.id = id;
  this.name = name;
 }
 public Builder age(int val) {
  this.age = val;
  return this;
 }
 public Builder sex(String val) {
  this.sex = val;
  return this;
 }
 public Builder phone(String val) {
  this.phone = val;
  return this;
 }
 public Builder address(String val) {
  this.address = val;
  return this;
 }
 public Builder desc(String val) {
  this.desc = val;
  return this;
 }
 public Person build() {
  return new Person(this);
 }
 }
}

Person是不可变得,所有的默认参数值都单独放在一个地方。builder的setter方法返回builder本身,以便可以链式调用。下面是客户端使用代码:

Person person = new Person.Builder(1, "张三")
                .age(18).sex("男").desc("测试使用builder模式").build();

Android源码中的Builder模式

  • AlertDialog源码
  • Universal-Image-Loader图片库
  • OkHttp的Request源码

优点:

  • 良好的封装性,使用建造者模式可以使客户端不比知道产品内部组成的细节
  • 建造者独立,容易扩展(可通过抽象———接口,抽象类)

缺点:

  • 会产生多余的Builder对象以及Director对象,消耗内存

总结 :Builder模式通常作为配置类的构建器将配置的构建和表示分离开来,同时也是将配置从目标类中隔离出来,避免过多的setter方法。

Javascript 相关文章推荐
判断页面是关闭还是刷新的js代码
Jan 28 Javascript
理解Javascript_05_原型继承原理
Oct 13 Javascript
在chrome浏览器中,防止input[text]和textarea在聚焦时出现黄色边框的解决方法
May 24 Javascript
jQuery写的日历(包括日历的样式及功能)
Apr 23 Javascript
JavaScript原型链示例分享
Jan 26 Javascript
jQuery实现拖动调整表格单元格大小的代码实例
Jan 13 Javascript
AngularJS控制器继承自另一控制器
May 09 Javascript
基于vue-cli 打包时抽离项目相关配置文件详解
Mar 07 Javascript
JS与jQuery实现ListBox上移,下移,左移,右移操作功能示例
May 31 jQuery
Node.js 使用axios读写influxDB的方法示例
Oct 26 Javascript
JS通过识别id、value值对checkbox设置选中状态
Feb 19 Javascript
解决vux 中popup 组件Mask 遮罩在最上层的问题
Nov 03 Javascript
使用vue-route 的 beforeEach 实现导航守卫(路由跳转前验证登录)功能
Mar 22 #Javascript
收集前端面试题之url、href、src
Mar 22 #Javascript
vue 的keep-alive缓存功能的实现
Mar 22 #Javascript
bootstrap中selectpicker下拉框使用方法实例
Mar 22 #Javascript
使用Vue开发动态刷新Echarts组件的教程详解
Mar 22 #Javascript
JavaScript分步实现一个出生日期的正则表达式
Mar 22 #Javascript
vuex 的简单使用
Mar 22 #Javascript
You might like
用PHP控制用户的浏览器--ob*函数的使用说明
2007/03/16 PHP
php类中的$this,static,final,const,self这几个关键字使用方法
2015/12/14 PHP
通过修改Laravel Auth使用salt和password进行认证用户详解
2017/08/17 PHP
PHP5.5新特性之yield理解与用法实例分析
2019/01/11 PHP
原生Js与jquery的多组处理, 仅展开一个区块的折叠效果
2011/01/09 Javascript
JavaScript栏目列表隐藏/显示简单实现
2013/04/03 Javascript
jQuery实现图片加载完成后改变图片大小的方法
2016/03/29 Javascript
用AngularJS的指令实现tabs切换效果
2016/08/31 Javascript
常用的javascript设计模式
2017/01/11 Javascript
canvas简单快速的实现知乎登录页背景效果
2017/05/08 Javascript
VUE2.0+ElementUI2.0表格el-table实现表头扩展el-tooltip
2018/11/30 Javascript
JS高阶函数原理与用法实例分析
2019/01/15 Javascript
微信小程序实现的图片保存功能示例
2019/04/24 Javascript
Vue项目中使用WebUploader实现文件上传的方法
2019/07/21 Javascript
Python解决鸡兔同笼问题的方法
2014/12/20 Python
在python中使用xlrd获取合并单元格的方法
2018/12/26 Python
python将处理好的图像保存到指定目录下的方法
2019/01/10 Python
Python和Go语言的区别总结
2019/02/20 Python
Django Celery异步任务队列的实现
2019/07/24 Python
Django中在xadmin中集成DjangoUeditor过程详解
2019/07/24 Python
Python传递参数的多种方式(小结)
2019/09/18 Python
pygame实现五子棋游戏
2019/10/29 Python
Python实现打印实心和空心菱形
2019/11/23 Python
Python3运算符常见用法分析
2020/02/14 Python
Python 读取xml数据,cv2裁剪图片实例
2020/03/10 Python
Pycharm2020.1安装中文语言插件的详细教程(不需要汉化)
2020/08/07 Python
python如何实现word批量转HTML
2020/09/30 Python
Python用dilb提取照片上人脸的示例
2020/10/26 Python
应届生英语教师求职信
2013/11/05 职场文书
护士演讲稿范文
2014/01/05 职场文书
学习党代会心得体会
2014/09/05 职场文书
先进教师个人事迹材料
2014/12/15 职场文书
2015年志愿者服务工作总结
2015/04/20 职场文书
详解JavaScript中Arguments对象用途
2021/08/30 Javascript
mysql5.7的安装及Navicate长久免费使用的实现过程
2021/11/17 MySQL
详解flex:1什么意思
2022/07/23 HTML / CSS