这几天在看顾浩鑫的《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. 【Go】Go基础(四):流程控制(控制结构)
  2. 理解 __doPostBack(转)
  3. django-无刷新ajax请求的试验
  4. Python工作笔记007---win10安装Python3.7.3_以及用pycharm创建Python项目_以及对System interpreter理解
  5. linux ora 00911,python – DatabaseError:ORA-00911:无效字符
  6. vue开发中v-for在Eslint的规则检查下出现:Elements in iteration expect to have 'v-bind:key' directives...
  7. Linux 天翼3G上网
  8. 2021下半年软考网络工程师上午真题(二)
  9. 工业软件研究框架_【软件开发】工业软件相关学习信息
  10. 移动应用开发 Android Studio安装教程
  11. ansible:变量调用set_fact和register
  12. windows未能启动计算机,电脑开机windows未能启动是怎么回事
  13. forEach的自动序号
  14. STM32的SRAM
  15. Tesseract OCR简介(一)
  16. Mysql-可重复读的隔离级别在什么情况下会出现幻读
  17. 一位博士论文的致谢部分
  18. 深度经验总结:快逸报表工具单数据集版本和多数据集版本的主要区别之一
  19. 多闪遭起诉:头条与腾讯社交战争升级背后的难隐之痛
  20. Android资源初探(一) 资源打包

热门文章

  1. 35kV电压补偿型SVG(STATCOM)
  2. BeeWare 峰器 中文文档 - 教程 0 - 让我们开始
  3. GAMES104 雾系统、反走样与后处理
  4. 高配电脑玩LOL(卡顿),i5-12600K,B660主板,2060亲测有效
  5. 用python读取csv文件并绘制波形及频谱
  6. 用js函数加判断做出对象中绝对值的效果
  7. MySQL按 年 月 周 日统计表中的数据
  8. wp-login.php 404页面,wordpress404页面制作完整的正确操作流程
  9. 发票自动识别功能前端开发(多表单动态生成)
  10. linux shell编程实例总结