这几天在看顾浩鑫的《Android高级进阶》,觉得这本书写得挺不错的,作为进阶一类,设计的知识面很多。在看的时候有一个知识点讲得很好,是关于Builder模式的,之前在学习设计模式的时候通常都是分析UML类图,学一些简单的接口和实现等,关于应用方面学习得比较少,看这本书的时候,刚好有一个章节专门对Builder模式进行讲解,以及它的变种在开发中的应用。学习完之后觉得受益颇多,故将此知识点记录下来。

这个章节最重要的内容是builder模式在javaBean中的应用。这里以一个User对象为例:

public class User {private String mName;private int mAge;private String mPhone;}

通常我都是这么写的,包括我早期在学习java的时候,教学也是这样讲的,凸显面向对象的封装性,然后给各个属性设置setter和getter方法,这种方法虽然可行,但却有着以下弊端:

①setter方法可能会被过度使用,尤其是在团队开发的时候,一个javaBean可能会经过几个程序员的代码中,设置了setter方法意味着哪个程序员都可以任意修改里面的属性值,这就容易造成一些混乱和错误,毕竟这些属性值是可变的,意味着对象在初始化的时候一些属性可以不对它进行赋值,等到后面某个环节再设置值,这样一来实例的整个状态也是不连续的,代码也会变得不优雅。

②开发过程中通常会对这样的可变类设置多个构造函数来满足多种属性值的初始化情况,在属性多的时候会变得难以维护;

③User类是可变的,这样一来就会失去不可变对象的很多好处,比如说线程安全问题,不可变对象是线程安全的。线程间的变量共享不需要利用特殊机制来保证同步,因为对象的值无法改变。这样一来可以减少同步机制的开销,二来可以降低并发错误的可能性。

所以可以考虑使用builder模式来构建javaBean对象。

public class User {private final String mName;private final int mAge;private final String mPhone;public String getmName() {return mName;}public int getmAge() {return mAge;}public String getmPhone() {return mPhone;}private  User(UserBuilder builder){mName=builder.mName;mAge=builder.mAge;mPhone=builder.mPhone;}public static  class  UserBuilder{private String mName;private int mAge;private String mPhone;public UserBuilder(String mName, int mAge) {this.mName = mName;this.mAge = mAge;}public UserBuilder age(int age){mAge=age;return this;}public UserBuilder name(String name){mName=name;return this;}public UserBuilder phone(String phone){mPhone=phone;return this;}public User build(){return new User(this);}}
}

这段代码是仿照《Android高级进阶》这本书写的,从上面的代码可以看出以下几点:

①User类是不可变的,所有属性值都是final类型并且只在构造函数中设置,只提供getter方法;

②User类的构造函数是私有的,不能直接实例化这个类;

③UserBuilder采用Fluent Interface的style(https://blog.csdn.net/time_hunter/article/details/8011124),这样调用返回的时候还是这个对象,可以继续调用该对象的方法,使得实例是个连续状态;

④User对象的属性值是由UserBuilder对象决定的,因为是建造者,所以builder对象可以是不连续状态,等到最终确定或者需要这个User对象的时候再调用build()方法构建对象。这个点非常重要,应用很广泛,因为现在举例的User类是比较简单的,只需要一个UserBuilder即可完成构建,但是在一些稍微复杂对象的构建场合,比如butterknife框架中,对于javaFile的构建包括了几个构建器,MethodBuilder,FieldBuilder等,以后我们再抽空分析下butterknife的源码。

创建User对象,使用builder:

public User getUser(){return new User.UserBuilder("狗娃",2).phone("138266").build();}

这样的创建方式是不是很熟悉?在很多开源框架也是用这种方式构建一些javaBean对象的,比如,在OkHttp框架对请求的封装和创建:

final Request request = new Request.Builder().url("https://github.com/hongyangAndroid").build();
private Request(Builder builder){this.url = builder.url;this.method = builder.method ;this.headers = builder.headers.build() ;this.body = builder.body ;this.tag = builder.tag != null ? builder.tag : this;
}

还有android的dialog创建也是这样的方式,这里就不过多展示了。此外,还有一点,如果嫌写builder麻烦,可以在android studio使用InnerBuilder这个插件来自动生成Builder类,再根据需要微调一下就行了。

后记:builder模式应用在javaBean对象也要看场合,不是所有的javaBean对象都适合用builder模式来构建,比如在社交类APP开发中,一个用户对象的信息通常是可变的,比如它的网名,性别,个人签名等等信息,而一些需要认证的信息比如个人姓名等,一旦设置就不允许随便更改的,所以这样的话一个javaBean对象就可能包含着可变和不可变的对象,具体情况需要具体分析。

builder模式构建JavaBean相关推荐

  1. 利用建造者(Builder)模式构建 Java 对象

    简介: 一般我们构建对象有两种方法,一是构造器,二是默认无参构造器创建对象后使用 set 方法一个个赋值.第一种方法我们需要写一个全参的构造方法,但这样我们在构造对象时有一些不需要填写的对象也要给他赋 ...

  2. JAVA Builder模式构建MAP/LIST的示例

    我们在构建一个MAP时,要不停的调用put,有时候看着觉得很麻烦,刚好,看了下builder模式,觉得这思路不错,于是乎,照着用builder模式写了一个构建MAP的示例,代码如下: import j ...

  3. 火遍全网的Hutool,如何使用Builder模式构建线程池

    前言 Builder 设计模式也叫做 构建者模式或者建造者模式,名字只是一种叫法,当聊起三种名称的时候知道是怎么回事就行 Builder 设计模式在作者编码过程中,属于比较常用的模式之一.优秀的设计模 ...

  4. GOF对Builder模式的定义(转载)

    (1)意图 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. (2)适用性 1. 当创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式: 2. 当构造过程必须允许 ...

  5. 构建器builder模式 + lombok @Builder的介绍及使用

    参考 https://juejin.im/post/6844903862600466439 注意⚠️: 带有@Builder的类,如果加了@NoArgsConstructor,那么也必须加@AllAr ...

  6. 设计模式系列-Builder模式(高效构建参数)

    引言 在Java编程中,常常需要为一个Bean构建成员变量或者构建参数,常用的方法有使用构造函数.使用JavaBean的set()方法,但是这两个方案或多或少都存在一定的缺点,于是今天的主角build ...

  7. JavaBean之Builder模式

    静态工厂和构造器 重载构造函数,分别包含多个不同的参数 无法很好地扩展到大量的可选参数 JavaBean方式 调用一个无参构造函数来创建对象,然后通过setter方法来设置必要参数 对象构造过程被分割 ...

  8. 11. 对象创建模式之 Builder模式(构建器)(不常用)

    1. 动机 在软件系统中,有时候面临着"一个"复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成:由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化, ...

  9. 设计模式之构建者(Builder)模式

    在五大设计原则的基础上经过GOF(四人组)的总结,得出了23种经典设计模式,其中分为三大类:创建型(5种).结构型(7种).行为型(11种).今天对创建型中的构建者(Builder)模式的思想进行了一 ...

最新文章

  1. Android 向右滑返回,退出当前activity
  2. android volley 上传图片 和参数,Android使用Volley上传文件
  3. 信息学奥赛一本通(1032:大象喝水查)
  4. Python高手之路【十】python基础之反射
  5. word2003快速排版工具栏_技巧 | 快速又好看,PPT制作不再难
  6. 数据清洗代码 寒老师
  7. apscheduler
  8. RHEL 5 rpm包安装bind
  9. 如何在工作中如鱼得水?有三点很重要
  10. 教你怎样做项目开发总结报告[转]
  11. 《Adobe Illustrator CC经典教程》—第0课0.2节使用Adobe Creative Cloud进行同步设置
  12. java 通过经纬度计算巨鹿,全国经纬度汇总表(全)
  13. python 写入文件 wb_python读写文件
  14. 华为云交付项目服务器配置表,云服务器交付确认表
  15. 基于ENVI的Landsat 7地表温度(LST)大气校正方法反演与地物温度分析
  16. Chrome 批量删除指定站点历史记录
  17. 中年转行,拥抱互联网(上)
  18. 思科、华为交换机链路聚合(LACP)配置实例
  19. nodejs request库拉取jsp接口 gb2312、GBK中文乱码解决方法
  20. 浅谈ERP系统实施后如何完善企业内部控制制度建设

热门文章

  1. 基于Opencv快速实现人脸识别(完整版)
  2. Java-学生宿舍管理系统
  3. [Apache Maven Shade Plugin] [example] [001] 官方例子:includes-excludes
  4. 关于CPU使用率飙升,我们需要了解什么?
  5. python遍历替换字典的key_Python遍历字典去key和value需要注意的点→enumerate和items()...
  6. 远程访问大华摄像头拍摄的视频
  7. 项目经理通过甘特图编制项目计划的方法
  8. 小米电视ES65 2022款 评测
  9. c语言typedef怎么自定义函数,c语言中typedef的用法
  10. C语言 typedef 关键字