设计模式-Builder模式详解
文章目录
- Builder模式详解
- Builder模式作用
- Builder模式创建
Builder模式详解
Builder模式也叫做建造者模式,是设计模式的一种,
就是将复杂对象的创建变得简单明了,使对象与他的表示进行分离,使得同样的创建过程,可以创建不同的对象.
我们这里讲变种 Builder模式(更加简单,明了),并非真正意义上的Builder模式;这种模式的目的用于简化(不可变)对象的构造(比如 Google 的 Protobuf 协议,在生成为 Java 代码后,都会提供一个 Builder 类去构造相关 Message)
Builder模式作用
解决让Object始终保持valid状态的问题,解决具有大量参数的构造函数不好用的问题
先看普通构建User类:
public class User {private String name;private String password;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String toString() {return "User(name=" + this.getName() + ", password=" + this.getPassword() + ")";}}
Builder模式:
public class UserB {private final String name;private final String password;public UserB(UserB.UserBuilder builder) {this.name = builder.name;this.password = builder.password;}public String getName() {return name;}public String getPassword() {return password;}public static final class UserBuilder {private final String name;private String password;private UserBuilder(String names) {this.name = names;}public String toString() {return "User(name=" + this.getName() + ", password=" + this.getPassword() + ")";}//构建参数是必传参数public static UserB.UserBuilder create(String name) {return new UserB.UserBuilder(name);}public UserB.UserBuilder withPassword(String password) {this.password = password;return this;}public UserB build() {return new UserB(this);}}}
这种传统的方式创建大家用的比较多,但是有很多缺点,如我要同时创建多个User,然后对应的User部分属性不一样,这样我要一个一个new就很麻烦,但是使用Builder模式就简单一点:
对应的main测试:
public static void main(String[] args) {User user = new User();user.setName("aaa");user.setPassword("123");System.out.println(user.toString());UserB.UserBuilder aaa = UserB.UserBuilder.create("aaa");aaa.withPassword("123");UserB build = aaa.build();aaa.withPassword("456");UserB build1 = aaa.build();aaa.withPassword("111");UserB build2 = aaa.build();System.out.println(build);System.out.println(build1);System.out.println(build2);}
生成的Build1,build2是不同的…
通过new生成的对象,在进行set属性的时候,对象的构造过程是非连续的,也就是说对象可处于一个构造不完全的状态,我们很容易写出将对象传入各个方法,每个方法去赋值对象的某一部分这样的代码,这其实引入了一个状态空间,如果状态空间是强可控的,那还好(但依然提高了维护成本,你需要牢牢掌握住对象的构造过程,什么字段在何处被赋值);如果不可控,那么就很难保证这个对象是否被正确的构造,可能在某个方法中覆盖了某字段,也可能遗漏了某字段导致 NPE。java编程现在都往不可变对象走,就像String类.
Builder模式创建
一般都是在User类里面新建静态内部UserBuilder 类并且提供静态create方法返回Builder,然后就是属性方法,返回Builder,最后就是Build方法,返回对应的实体类.
对应的create方法一般是必传字段,这时候就可以设置为final的;而实体类里面属性就都是final的;
这种Builder模式几乎都差不多,如果实体类很多的话,我们会写很多重复的代码,这时候就很麻烦,推荐使用Lombok的 @Builder 注解,我们就不需要写任何代码了,我们看看通过@Builder注解生成的Builder类:
使用:
@Builder
@Data
public class UserLombok {private final String name;private final String password;public static void main(String[] args) {UserLombok.UserLombokBuilder build = new UserLombokBuilder().name("aa").password("aa");UserLombok build1 = build.build();UserLombok build2 = build.build();System.out.println(build.name);}}
这里是对应的字节码,反编译的class类:
public class UserLombok {private final String name;private final String password;public static void main(String[] args) {UserLombok.UserLombokBuilder build = (new UserLombok.UserLombokBuilder()).name("aa").password("aa");UserLombok build1 = build.build();UserLombok build2 = build.build();System.out.println(build.name);}UserLombok(String name, String password) {this.name = name;this.password = password;}public static UserLombok.UserLombokBuilder builder() {return new UserLombok.UserLombokBuilder();}public String getName() {return this.name;}public String getPassword() {return this.password;}public String toString() {return "UserLombok(name=" + this.getName() + ", password=" + this.getPassword() + ")";}public static class UserLombokBuilder {private String name;private String password;UserLombokBuilder() {}public UserLombok.UserLombokBuilder name(String name) {this.name = name;return this;}public UserLombok.UserLombokBuilder password(String password) {this.password = password;return this;}public UserLombok build() {return new UserLombok(this.name, this.password);}public String toString() {return "UserLombok.UserLombokBuilder(name=" + this.name + ", password=" + this.password + ")";}}
}
同样,如果公司不推荐使用lombok的话,也可以使用idea 的Builder插件来生成部分代码,具体还得看公司的情况,统一才是王道…
设计模式-Builder模式详解相关推荐
- 设计模式——状态模式详解
0. 前言 写在最前面,本人的设计模式类博文,建议先看博文前半部分的理论介绍,再看后半部分的实例分析,最后再返回来复习一遍理论介绍,这时候你就会发现我在重点处标红的用心,对于帮助你理解设计模式有奇效哦 ...
- Android : Builder模式 详解及学习使用
在此声明:以下内容由书籍 <Android高级进阶>学习而来. Builder模式是一种设计模式,最初被介绍于<设计模式:可复用面向对象软件的基础>,目前在Java及Andro ...
- Java设计模式-模板方法模式详解
Java设计模式-模板方法模式 文章目录 Java设计模式-模板方法模式 0.前言 1.模板方法原理 2.模板方法模式中的角色 3.模板方法模式的UML类图 4.代码实现 5.编码测试 6.模板模式中 ...
- 软件设计模式——代理模式详解
摘要 动态代理是Java语言中非常经典的一种设计模式,也是所有设计模式中最难理解的一种.那什么是代理设计模式?代理设计的基础概念就是通过代理控制对象的访问,可以在这个对象调用方法之前.调用方法之后去处 ...
- 设计模式——策略模式详解
0. 前言 写在最前面,本人的设计模式类博文,建议先看博文前半部分的理论介绍,再看后半部分的实例分析,最后再返回来复习一遍理论介绍,这时候你就会发现我在重点处标红的用心,对于帮助你理解设计模式有奇效哦 ...
- 阿里软件测试工程师手把手教学:自动化脚本中的设计模式-PO模式详解
请点击输入图片描述(最多18字) 当我们以脚本的形式编写了大量的自动化测试代码后,很容易发现代码可读性太差了.任何一个测试脚本几乎毫无扩展能力或者说扩展起来只能修改边边角角.一旦被测系统的UI层发生变 ...
- 设计模式——外观模式详解
0. 前言 写在最前面,本人的设计模式类博文,建议先看博文前半部分的理论介绍,再看后半部分的实例分析,最后再返回来复习一遍理论介绍,这时候你就会发现我在重点处标红的用心,对于帮助你理解设计模式有奇效哦 ...
- java设计模式组合模式详解_《JAVA设计模式》之组合模式(Composite)
在阎宏博士的<JAVA与模式>一书中开头是这样描述合成(Composite)模式的:html 合成模式属于对象的结构模式,有时又叫作"部分--总体"模式.合成模式将对象 ...
- C++设计模式 - 代理模式详解一
代理模式:提供一种可以对真实对象的访问对象,隐藏真实的对象,去除真实对象的非必要的职责. 大家都喜欢玩游戏,单机版游戏如红警.CS.暗黑了等(不小心就暴露了年龄),网络游戏如传奇.魔兽以及吃鸡游戏.王 ...
- 学习笔记(20):第2章 架构师内功心法之设计模式 -策略模式详解
立即学习:https://edu.csdn.net/course/play/28941/403582?utm_source=blogtoedu 策略模式:提供多种算法,由使用者来选择使用哪种方式来实现 ...
最新文章
- Django之ModelForm验证
- Json格式的netconf转成NormalizedNode
- Scratch-介绍“克隆”
- java mail 不用密码_iPhone 无需越狱,简单给 App 加密码锁
- 电脑mod_(电脑游戏) 层层恐惧2、冒险游戏——电脑配置要求单机游戏MOD攻略修改器下载...
- Axis2生成wsdl的一种方法
- 详细解析Linux /etc/shadow文件
- Android基础| 1G-4G的介绍
- 明日之后无限金条服务器,明日之后:无限金条bug 你值得收藏
- Linux之ubuntu离线安装软件包
- 包装设计实战案例教学
- php文字添加投影,视频加动态标题文字 视频标题文字添加阴影边框 给视频加上炫酷的文字标题...
- 【cocos creator 3.x】精灵图片不显示
- 【程序员面试系列】手把手教你如何面试,你要的我都有(工作项目篇)
- 3dmax,查看场景中所有材质
- Backup Exec 数据库空间不足
- mysql id in 走索引 ??
- FPGA视觉从入门到放弃——懒人的支持向量机
- Java项目版本构建是什么意思_Java项目的构建和版本号(ant,cvs,hudson)
- linux中安装maven插件,Maven插件wagon