本篇将拿构造器来和使用builder设计模式比较着解释应该如何创建不可变对象
使用此种方式可以使你的代码更具有可读性,首先,让我们来看下如果使用如下的接收三个BigDecimal类型参数的构造器来构建的CashBalance对象是多么的不优雅。然后我们会在看下使用builder模式是怎样让你的代码更简洁的。
当下次你在面试中被问及设计模式的时候,你可以拿这个实现来和使用很频繁的工厂模式和单例模式做个比较。这篇文章还设计到其他两个重要的概念(不可变性和线程安全)
import java.math.BigDecimal; /** * 因为不可变,所以是线程安全的对象 */ public final class CashBalance { private BigDecimal initialBalance; private BigDecimal totCredits; private BigDecimal totDebits; //构造器 public CashBalance(BigDecimal initialBalance, BigDecimal totCredits, BigDecimal totDebits) { this.initialBalance = initialBalance; this.totCredits = totCredits; this.totDebits = totDebits; } //不可变对象中只提供getter方法,不提供setter方法 }
因此,这段代码哪里不优雅?首先它的构造器需要三个BigDecimal的参数,在使用类的时候对于参数的意义来说不怎么直观,你说不清哪个参数是initialBalance,哪个参数是totCredits,如果你使用下面的方式来调用构造器会更好
CashBalance bal = new CashBalance(initialBalance:BigDecimal.valueOf(250.00), totCredits:BigDecimal.valueOf(250.00), totDebits:BigDecimal.valueOf(250.00));
很不幸的是,你不能使用上面的语法来写程序,你只能通过下面的方式调用它.
CashBalance bal = new CashBalance(BigDecimal.valueOf(250.00), BigDecimal.valueOf(250.00), BigDecimal.valueOf(250.00));
通过一个空构造器和三个setter方法来实现代码会更为优雅,但是对象必须是不可变的。下面是拯救你的构造器设计模式的代码。通过定义一个内部类来构造CashBalance对象。
import java.math.BigDecimal; /** * 不可变,所以线程安全 */ public final class CashBalance { private BigDecimal initialBalance, totCredits, totDebits; //构造器 public CashBalance(CashBalanceBuilder builder) { this.initialBalance = builder.initialBalance; this.totCredits = builder.totCredits; this.totDebits = builder.totDebits; } //构造器模式 public static class CashBalanceBuilder { // 有需要构造的对象一致的字段列表 protected BigDecimal initialBalance, totCredits, totDebits; //将访问权限设置为包内访问 void setInitialBalance(BigDecimal initialBalance) { this.initialBalance = initialBalance; } void setTotCredits(BigDecimal totCredits) { this.totCredits = totCredits; } void setTotDebits(BigDecimal totDebits) { this.totDebits = totDebits; } } //只提供setter方法 }
现在,你可以像下面调用一样在类外面构造CashBalance
public static void main(String[] args) { CashBalance.CashBalanceBuilder builder = new CashBalance.CashBalanceBuilder(); builder.setInitialBalance(BigDecimal.valueOf(250.00)); builder.setTotCredits(BigDecimal.valueOf(250.00)); builder.setTotDebits(BigDecimal.valueOf(250.00)); CashBalance bal = new CashBalance(builder); }
上面的代码完成了,但是如果你还有更多的字段,构造的代码就会显得很臃肿。这个可以用下面的方式来改善。
下面代码的改进是通过修改void类型的setter方法设值后返回builder自身来实现的
import java.math.BigDecimal; /** * 不可变线程安全对象 */ public final class CashBalance { private BigDecimal initialBalance, totCredits, totDebits; //构造器 public CashBalance(CashBalanceBuilder builder) { this.initialBalance = builder.initialBalance; this.totCredits = builder.totCredits; this.totDebits = builder.totDebits; } public static class CashBalanceBuilder { //has same fields as the object it is going to build protected BigDecimal initialBalance, totCredits, totDebits; //define the setters that return itself CashBalanceBuilder setInitialBalance(BigDecimal initialBalance) { this.initialBalance = initialBalance; return this; } CashBalanceBuilder setTotCredits(BigDecimal totCredits) { this.totCredits = totCredits; return this; } CashBalanceBuilder setTotDebits(BigDecimal totDebits) { this.totDebits = totDebits; return this; } } }
代码修改带来的优雅是现在可以通过下面的构造方式调用:
public static void main(String[] args) { CashBalance.CashBalanceBuilder builder = new CashBalance.CashBalanceBuilder() .setInitialBalance(BigDecimal.valueOf(250.00)) .setTotCredits(BigDecimal.valueOf(250.00)) .setTotDebits(BigDecimal.valueOf(250.00)); CashBalance bal = new CashBalance(builder); }
因此这些秘诀可以让你在和职场达人的面试中赢得加分
相关推荐
Information Builders公司介绍
属性是非最终的,因此对象是可变的,请参见 IDEA InnerBuilder IDEA InnerBuilder 示例。 优点: 字段仅需指定,所有方法都可以由IDEA生成。 缺点: 你必须使用; 所有样板仍驻留在源代码控制系统中。 Goo
jbw-builders, 某些基础类的生成器类别 jbw-builderNSURL 和 NSDate的生成器类别。 生成器类别添加了一个基于构造器 Pattern的便捷初始化器,... 不创建自定义构建器对象,而是使用基础 NS*Components 对象中的。By J
Information Builders产品列表
##Overview Builders 是一个,它生成一个 ,然后可用于创建和/或填充对象。 要使用 Builders,只需将添加到您的类路径,并注释您要创建构建器的类以使用注释。 然后构建器将执行以下操作: 默认生成 Builder 类(您...
Angular-angular-builders.zip,angular cli@angular builders的一组自定义生成器,Angularjs于2016年发布,是Angularjs的重写版。它专注于良好的移动开发、模块化和改进的依赖注入。angular的设计目的是全面解决开发...
Cmake Error at builders/vpx.cmake:89 Cmake Error at builders/vpx.cmake:88 Cmake Error at builders/vpx.cmake:87 Cmake Error at builders/vpx.cmake:77 file not found WORK/desktop/cmake/windowsenv_libpath...
使用Gatsby CLI创建一个新站点,并指定博客启动器。 # clone this repo git clone https://github.com/junaid33/opensource.builders 开始开发。 导航到新站点的目录并启动。 cd opensource.builders yarn install...
nano_builders
现在的建设者 这是一个包含ZEIT团队提供的的monorepo。 该存储库已移至
海洋建筑商服务器Ocean Builders应用程序为seapod所有者提供了在任何iOS和Android设备上的完全控制,监视和自定义选项。 该系统旨在通过提供工具来帮助控制海洋吊舱创建过程,从而使用户能够控制海洋建造者的海洋...
前端开源库-Builders建设者,资产建设者:css,js,sprites。
预构建的映像可在gcr.io/cloud-builders/... ,包括: bazel :运行工具 curl :运行工具 docker :运行工具 dotnet :运行工具 gcloud :运行工具 gcs-fetcher :从Google Cloud Storage有效地获取对象 git :...
抽象精品ppt模板nano_builders049
@ angular-builders 该存储库的目的是整合Angular构建立面的所有社区构建器。 所有构建器的最新版本都需要Angular CLI 11 建筑商 (替代ng eject ) (允许使用Jest运行ng test ) (来自示例助洗剂文章) 保持...
.net项目中开发中有时会用到动态构建SQL语句,根据本人使用SQL的经验,写出了一些常用的SQL语句构建类,使得SQL的生成更自然。比起用字符串拼接不但好用而且不易出错。 如: InsertBuilder insertBuilder = new ...
Patterns and Principles for CRM Online Solution Builders
Builders-Utilities是Alex_deGrote要求的插件,他在McBcon的我的小组讨论会上赢得了插件赠品。 该插件是许多有助于构建的小功能的集合。 链接 建造 建议使用Gradle构建项目。 在主项目目录中使用./gradlew build来...
也论该不该在项目中使用存储过程代替SQL语句 如何使数据库中的表更有弹性,更易于扩展 存储过程——天使还是魔鬼 如何获取MSSQLServer,Oracel,Access中的数据字典信息 C#中利用GetOleDbSchemaTable获取数据库内表信息...