流利的对象创建

关于此主题的文章很多(绝大多数),但我只是想贡献我的两分钱,写一篇简短的文章,介绍如何使用Java中的Fluent Object Creation模式或对象构建器实例化Value Objects。
值对象是由其状态(值)而不是其在内存中的地址定义的抽象。 价值对象的示例是诸如金钱,数字,坐标等之类的东西。它们不是用来描述业务对象,而是用于描述具体不可分割的实体。 此外,它们是将其添加到收藏和地图的绝佳选择。

在Java中, Value Objects应该声明为final,并且不提供setter方法,基本上使它在创建后保持不变,这是非常重要的
需求。 最终声明它们会使它们无法充当父对象。 这是通过设计完成的,因为价值对象应该对小的具体实体进行建模。 原因是我们应该能够创建和比较这些对象的多个副本,这总是由状态而不是通过引用来完成。 另外,您应该声明适当的equals()hashCode()方法以符合适当的值对象的条件。 在C ++中,适用相同的原理。 在C ++中,您应该使用Copy构造函数并重载赋值和比较运算符。 流利的对象创建模式使价值对象实例化优雅而干净。 很快就会看到,使用流畅的对象创建可以带来很多好处。

从API用户的角度来看,应用此模式的最终结果将如下所示:

Money fiveEuros = new Money.Builder().currency(Currency.EURO).value(5.0L).countryOfOrigin("Spain").type("Coin").reverse("Map of Europe").obverse("Map of Spain").addColor("Bronze").addColor("Silver").year("1880")
.build();

我认为您会同意,这种模式与之相反,流程更加顺畅:

Money fiveEuros = new Money();
fiveEuros.setCurrency(Currency.EURO);
fiveEuros.setValue(5.0L);
fiveEuros.countryOfOrigin("Spain");
fiveEuros.type("Coin");
fiveEuros.reverse("Map of Europe");
fiveEuros.obverse("Map of Spain");List<String> colors = new ArrayList<String>();
for(String color: new String[] {"Bronze", "Silver"}) {colors.add(color);
}fiveEuros.setColors(colors);
fiveEuros.setYear("1880");

这似乎坏了,并且有很多打字和重复。 在我看来,这是一个构建非常大的价值对象的示例,其中大多数往往很小。 在讨论以这种方式创建对象的好处之前,让我们看一下这种模式的结构:

public final class Money {private Long value;private String countryOfOrigin;     private Currency currency;private String type; private String reverse;private String obverse;    private List<String> colors;private Date year;    private Money() {   }// -- getters, hashCode, equals -- //// Static inner Builder classpublic static class Builder {private Money _temp = new Money();
public Builder value(Long val) {
_temp.value = val;
return this;
}
public Builder countryOfOrigin(String countryOfOrigin) {
_temp.contryOfOrigin = countryOfOrigin;return this;
}
public Builder currency(Currency c) {
_temp.currency = c;
return this;
}
public Builder type(String t) {
_temp.type = t;
return this;
}
public Builder reverse(String r) {
_temp.reverse = r;
return this;
}public Builder obverse(String o) {
_temp.obverse = o;
return this;
}public Builder addColor(String c) {
if(_temp.colors == null) {_temp.colors = new ArrayList<String>(); }_temp.colors.add(c);
return this;
}public Builder year(String y) {if(y == null || y.isEmpty()) {_temp.year = new Date();}else {_temp.year = DateFormat.parse(y);}
return this;
}
public Money build() {// Validate objectif(Strings.isNullOrEmpty(_temp.name) || _temp.currency == null) {throw new IllegalArgumentException("Coin currency and value required");}
return _temp;
}}
}

这也是一个问题,但是我更喜欢静态内部类方法。 我喜欢将构建者称为“规范性”
Money.Builder。 还需要将其设为静态 ,因为构建器实例需要独立于封闭类生活。 我喜欢这种模式,因为它具有以下优点:

  1. 更大的对象封装:通过将Money构造函数设为私有(这只是样式),我可以轻松地使用构建器强制执行对象构造。 这完全隐藏了创建该对象的所有复杂性:列表创建,日期解析等。从用户的角度来看,最终得到的是一个易于实例化的对象。 我的插图很简单,但是可以想象更复杂的对象图。
  2. 代码可读性:使用此模式创建对象,使单元测试和代码非常易于阅读和遵循。
  3. 长期减少键入:即使您必须为每个添加的属性添加额外的构建器方法,但长期保存的键入量还是值得的。

结论

使用流畅的创建模式需要更多的工作,但是最终获得回报的好处。 它使实例化对象非常优雅和干净。 您不必将其与Value Objects一起使用,使用Fluent Object Creation的大多数好处是当您需要构建相当复杂的对象图时,但是我想证明它也可以适用 小价值的对象。

参考:我们的JCG合作伙伴 Luis Atencio在Reflective Thought博客上的Fluent Object Creation 。

翻译自: https://www.javacodegeeks.com/2013/01/fluent-object-creation.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/369945.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机等级考试试题4,计算机等级考试二级模拟试题4

计算机等级考试二级模拟试题计算机等级考试二级模拟试题4基础知识与FOXBASE程序设计(考试时间120分钟&#xff0c;满分100分)一、选择题((1)-(40)每个选项1分,(41)-(50)每个选项2分,共60分)下列各题A)、B)、C)、D)、四个有选项中,只有一个选项是正确的(1)通常所说的主机主要包括…

springboot怎么替代jsp_如何在SpringBoot中使用JSP ?

1. 在pom.xm中加入支持JSP的依赖org.apache.tomcat.embedtomcat-embed-jasperprovidedjavax.servlet.jsp.jstljstl-api1.22. 在src/main/resources/application.properties文件中配置JSP和传统Spring MVC中和view的关联# MVCspring.view.prefix/WEB-INF/views/spring.view.suff…

css选择器的综合使用

代码实现&#xff1a; 1 <!DOCTYPE html>2 <html lang"en">3 <head>4 <meta charset"utf-8">5 <title>css的综合使用</title>6 <style>7 div {8 colo…

启动tomcat时 一闪而过解决方法

【前文】 在实际开发中一般都是eclipsetomcat(也许还会用到tomcat的插件)&#xff0c;我们只需要在eclipse中单击servers上的按钮就可以成功启动tomcat了&#xff0c; 但是如果想在tomcat的安装目录下 双击startup.bat启动时却一闪而过了。这是为什么呢&#xff08;tomcat启动失…

Google Guava多集

继续这次番石榴之旅&#xff0c;我们到达了Multiset 。 我可能不像Multimaps或Bimaps那样使用它&#xff0c;但是它确实有它的用途。 那么什么是多重集&#xff1f; 也许您可以猜到它是一个可以容纳同一对象的多个实例的集合。 这不仅仅是列表吗&#xff1f; 在Java中&#x…

用javascript实现简单的用户登录验证

用javascript实现简单的用户登录验证 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Document</title> </head> <body><script type"text/javascript">function c…

怎么把计算机改程序,怎样修改程序软件

大家好&#xff0c;我是时间财富网智能客服时间君&#xff0c;上述问题将由我为大家进行解答。修改程序软件的方法是&#xff1a;这个必须要会编程才行&#xff1b;不会编程的话那是不可能的&#xff1b;对它进行反编译&#xff1b;脱壳&#xff1b;反编译好再把它重新加壳。程…

HTML的display属性将行内元素、块状元素、行内块状元素互相转换以及三者的区别

1.行内元素 查看演示 (1)设置宽高无效 (2)对margin仅设置左右方向有效&#xff0c;上下无效&#xff1b;padding设置上下左右都有效&#xff0c;即会撑大空间 (3)不会自动进行换行 <html> <head> <meta charset"utf-8" /> <title>行内元…

linux里面三剑客的重要作用

在服务器日志fresh.log中&#xff0c;找到所有报错的日期 $ sed -n /Error/p | awk {print $1} fresh.log grep:查找sed:行编辑器awk:文本处理工具 正则表达式的应用场景查找所有包含xxx的行取出以abc开头的所有单词匹配两位数、密码、QQ号、身份证号等 查找、取出、匹配符合条…

i2c通信 msp430g2553_关于msp430G2553的I2C串行通信

这是msp430g2xx3_uscib0_i2c_09例程&#xff0c;i2c从机接收数据的程序&#xff0c;请高手指点一下&#xff0c;为什么读取UCB0RXBUF是在发送中断中&#xff1f;接收机是在什么时候进入发送中断的&#xff1f;#include unsigned char *PRxData; // Pointer to RX dataunsigned …

Google Guava BiMaps

接下来的番石榴之旅&#xff0c;是另一种有用的收藏类型BiMap 。 实际上&#xff0c;这非常简单&#xff0c;BiMap只是双向地图。 反转地图 普通的Java映射是一组键和值&#xff0c;您可以按键查找值&#xff0c;这非常有用&#xff0c;例如&#xff0c;说我想创建一个&#x…

老大写得一个非常高大上的Makefile,包括非常多语法:

一个非常高大上的Makefile&#xff0c;包括非常多语法&#xff1a; TARGET api-login INSTALL_PATH /huishoubao/cgiinclude ../../implements/log/Makefile.log include ../../implements/tools/Makefile.tools include ../../implements/db/Makefile.db include ../../impl…

计算机等级考试模拟题卷子,二级VB模拟试卷 1

一、选择题&#xff1a;35题&#xff0c;2分/题&#xff0c;共70分下列各题A)、B)、C)、D)四个选项中&#xff0c;只有一个选项是正确的&#xff0c;请将正确选项涂写在答题卡相应位置上&#xff0c;答在试卷上不得分。1.假定窗体有一个标签&#xff0c;名为Label1,为了使该标签…

bugly怎么读_腾讯Bugly巨坑:使用不当造成UI界面卡死

本文由CocoaChina网友gagaga投稿前言Bugly和dispatch_once使用不当&#xff0c;会造成UI界面卡死。笔者在前段时间碰见了这样的一个卡死的情况&#xff0c;特意记录下来。iOS开发者或多或少都听过或用过Bugly。它是腾讯开发的一个SDK&#xff0c;用来捕捉App中的crash。对于dis…

复习HTML CSS(5)

n <meta>标记 <meta>的主要作用&#xff0c;是提供网页的源信息。比如&#xff1a;指定网页的搜索关键字 <meta>标记有两个属性&#xff1a;http-equiv和name。 1、 http-equiv属性 功能&#xff1a;模拟http协议文件头信息&#xff0c;当信息从服务器端传…

『cs231n』卷积神经网络工程实践技巧_下

概述 计算加速 方法一&#xff1a; 由于计算机计算矩阵乘法速度非常快&#xff0c;所以这是一个虽然提高内存消耗但是计算速度显著上升的方法&#xff0c;把feature map中的感受野&#xff08;包含重叠的部分&#xff0c;所以会加大内存消耗&#xff09;和卷积核全部拉伸成为向…

Spring属性占位符配置器–一些不太明显的选项

Spring的PropertySourcesPlaceholderConfigurer用于从XML或Java Config中定义的Spring bean定义外部化属性。 PlaceholderConfigurer支持的一些选项在文档中并不明显&#xff0c;但是很有趣并且可能有用。 首先&#xff0c;以Spring文档中的示例为例&#xff0c;考虑一个属性文…

计算机扬天m400c联想,【联想扬天M参数】联想扬天M系列台式电脑参数-ZOL中关村在线...

CPU型号内存容量硬盘容量屏幕尺寸显卡类型 价格详细对比Intel 奔腾双核 E52002GB DDRII 667MHz250GB SATAII 7200转高速防震硬盘集成显卡对比Intel 奔腾4 631512MBGB 512MB DDRII53380GB 7200转集成显卡对比Intel Atom 2301GBGB DDRII160GB 7200转高速防震硬盘集成显卡对比Inte…

SqlServer知识点

在公司天天写Sql写,存储过程,但是公司工具模板把创建的语句都写好了,只负责写里面的逻辑,久而久之,创建语句都不会写了。还有一些知识点都很模糊,平常使用的时候都不清楚,稀里糊涂的就在用。在这里整理一下。巩固复习。 一.存储过程。 1.存储过程类似编程语言的里面的函数,方法…

css3 flex 布局

今天做一个小实战&#xff0c;需要让一个登录框始终保持水平和垂直居中&#xff0c;第一个想到的就是通过定位&#xff08;要想让一个div居中&#xff0c;采用定位可以解决&#xff0c;示例&#xff09;&#xff0c; 然后开始接触flex布局&#xff0c;学完感觉真的好用&#x…