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一组验证函数
Dec 20 Javascript
js 中的switch表达式使用示例
Jun 03 Javascript
JS根据变量保存方法名并执行方法示例
Apr 04 Javascript
JavaScript中for循环的使用详解
Jun 03 Javascript
简单学习JavaScript中的for语句循环结构
Nov 10 Javascript
基于jQuery实现数字滚动效果
Jan 16 Javascript
jQuery简单获取DIV和A标签元素位置的方法
Feb 07 Javascript
Bootstrap笔记之缩略图、警告框实例详解
Mar 09 Javascript
koa上传excel文件并解析的实现方法
Aug 09 Javascript
vue服务端渲染缓存应用详解
Sep 12 Javascript
解决JQuery的ajax函数执行失败alert函数弹框一闪而过问题
Apr 10 jQuery
详解ES6 export default 和 import语句中的解构赋值
May 28 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正则
2006/07/07 PHP
php使用base64加密解密图片示例分享
2014/01/20 PHP
PHP面向对象程序设计高级特性详解(接口,继承,抽象类,析构,克隆等)
2016/12/02 PHP
如何在PHP环境中使用ProtoBuf数据格式
2020/06/19 PHP
javascript String 的扩展方法集合
2008/06/01 Javascript
js 实现无缝滚动 兼容IE和FF
2009/07/15 Javascript
js 实现打印网页中定义的部分内容的代码
2010/04/01 Javascript
jQuery 学习第五课 Ajax 使用说明
2010/05/17 Javascript
遨游,飞飞,IE,空中网 浏览器无提示关闭方法
2011/07/11 Javascript
JS 如果改变span标签的是否隐藏属性
2011/10/06 Javascript
讨论html与javascript在浏览器中的加载顺序问题
2013/11/27 Javascript
用nodejs的实现原理和搭建服务器(动态)
2016/08/10 NodeJs
jQuery实现的瀑布流加载效果示例
2016/09/13 Javascript
微信js-sdk地理位置接口用法示例
2016/10/12 Javascript
Vue实现双向绑定的方法
2016/12/22 Javascript
判断div滑动到底部的scroll实例代码
2017/11/15 Javascript
解决linux下node.js全局模块找不到的问题
2018/05/15 Javascript
vue项目中jsonp跨域获取qq音乐首页推荐问题
2018/05/30 Javascript
vue实现点击按钮下载文件功能
2019/10/11 Javascript
Ruby元编程基础学习笔记整理
2016/07/02 Python
Python基于回溯法子集树模板解决找零问题示例
2017/09/11 Python
Java实现的执行python脚本工具类示例【使用jython.jar】
2018/03/29 Python
Python socket实现简单聊天室
2018/04/01 Python
python常见字符串处理函数与用法汇总
2019/10/30 Python
python如何进入交互模式
2020/07/06 Python
HTML5 script元素async、defer异步加载使用介绍
2013/08/23 HTML / CSS
HTML5 video循环播放多个视频的方法步骤
2020/08/06 HTML / CSS
沙特阿拉伯家用电器和电子产品购物网站:Sheta and Saif
2020/04/03 全球购物
数字天堂软件测试面试题
2012/12/23 面试题
大班上学期幼儿评语
2014/04/30 职场文书
机械制造专业大学生自我鉴定
2014/09/19 职场文书
4S店销售内勤岗位职责
2015/04/13 职场文书
2015年医院护理部工作总结
2015/04/23 职场文书
医生行业员工的辞职信
2019/06/24 职场文书
高考满分作文赏析(2篇)
2019/08/12 职场文书
面试必问:圣杯布局和双飞翼布局的区别
2021/05/13 HTML / CSS