我喜欢构建器模式的三个原因

有三种方法可以用Java编程语言创建新对象:

  1. 伸缩构造函数(反)模式
  2. Javabeans模式
  3. 建造者模式

与其他两种方法相比,我更喜欢使用构建器模式。

为什么?

Joshua Bloch描述了构建器模式以及在Effective Java中使用它的好处。 他的工作非常出色,在这篇博客文章中,我将不再重复这些好处。

取而代之的是,我将描述为什么我更喜欢构建器模式而不是伸缩构造器模式和Javabeans模式的三个其他原因。

1.帮助您进行更好的设计

使用伸缩构造函数模式或Javabeans模式意味着必须在创建实际对象之前创建所创建对象的属性。

这可能是问题,也可能不是问题。

如果使用外部服务获取创建对象的属性,则不会有问题。 但是,如果在创建“目标”对象的方法中创建了属性,则将出现问题。

在后一种情况下,创建的对象的生命周期通常绑定到“目标”对象的生命周期。

在这种情况下,构建器模式可以帮助您使用称为聚合的域驱动设计(DDD)模式。 Martin Fowler指定聚合模式如下:

DDD聚合是域对象的群集,可以将它们视为一个单元。 一个示例可能是一个订单及其订单项,它们将是单独的对象,但是将订单(连同其订单项)视为一个单独的汇总很有用。

构建器模式可以帮助您以将域模型划分为聚合的方式设计代码。 这意味着属于聚合的所有对象都是由聚合根对象(订单)创建的,并且只能通过聚合根对象进行访问。

这将构造关系与逻辑关系移到它所属的位置。

2.让你思考

以传统方式编写代码很容易,因为您无需思考。 您所要做的就是编写将信息从一个地方复制到另一个地方的代码。 可能要花一些时间,但这对您来说不是问题,因为您处于舒适区。

也许您只是想处理代码而不考虑自己在做什么。

我不是那样的人(你也不应该那样)。

构建器模式迫使您考虑对象。 更具体地说,它迫使您考虑以下事项:

  • 您必须找出对象的必需和可选属性。
  • 您必须确定生命周期绑定到所创建对象的生命周期的属性,并设计构建器以使其更加突出。
  • 您必须确定在创建对象后无法更新哪些属性(并将这些属性标记为最终属性)。
  • 您必须决定可以更新哪些属性,并找到更新它们的最佳方法。

找到这些问题的答案有助于您编写更好的代码。 我可以保证,如果您花时间查找这些问题的答案,您的代码将比自动驾驶仪上编写的代码好得多。

3.它可以帮助您创建特定于域的语言

如果使用伸缩构造函数模式或Javabeans模式创建新对象,则很难在代码中添加业务含义。 您可以按照以下原则尝试改善情况:

  • 可以向构造函数参数添加业务含义的唯一方法是以适当的方式命名参数。 这很难做到,即使您做对了,结果也不是最佳的。
  • 如果使用设置器,则当然可以用一种添加设置器方法的方式来命名它们。 但是,您有多少次看到以该原理命名的setter方法?

在100个对象中,有99个创建的对象只是没有意义的对象。 他们保存数据。 就这些。

使用构建器模式时,可以通过命名构建器类的方法来创建用于创建新对象的域特定语言(DSL) 。 这可以帮助您在创建新对象的代码中添加业务含义。

这就提出了一个问题:如何更新对象的属性?

当然,您可能会很无聊,并使用setter方法来更新对象的各个属性。 但是您也可以做一些完全不同的事情。

您可以将这些属性分为有意义的组,而不用更新单个属性,并且可以通过一种方法更新这些属性的值。 如果正确命名此方法,则可以创建DSL来更新现有对象的信息。

这不是银弹

布雷克•考德威尔(Blake Caldwell)表示, 对于构造器来说,构造器模式本质上不太容易错误 。 我同意他的观点。

当您开始使用构建器模式时,首先要注意的是创建新对象的代码更易于编写和阅读。 但是,一段时间后,您可能还会注意到其他好处。 我知道我做到了。

但是,重要的是要了解构建器模式不是灵丹妙药

我认为, 没有人会因为一种最佳实践而遵循最佳实践 。 这也适用于构建器模式。

如果您的对象只有几个构造函数参数,则使用构建器模式没有任何意义。 但是,由于此博客文章(以及Effective Java)中所述的好处,因此您每次必须创建新对象时都应考虑使用构建器模式。

参考: Petri Kainulainen博客上我喜欢 JCG合作伙伴 Petri Kainulainen 的构建器模式的三个原因 。

翻译自: https://www.javacodegeeks.com/2014/02/three-reasons-why-i-like-the-builder-pattern.html

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

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

相关文章

表单php跳转页面跳转,form表单页面跳转方式提交练习

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼//form表单提交练习/*新建一个form.html网页用来书写前端HTML表单*/表单提交练习姓名:年龄:电话:地址:QQ:自我评价://以上功能可自己添加或修改/*在form.html网页的基础上新建一个foms.php网页关联之前的form.html网页并书写php测试…

.NetCore模拟Postman的BasicAuth生成Authrization

一、思路 BasicAuth 是一种简单权限&#xff0c;传输UserName<userName>,Password<password> 1.用:连接Username,Password 2.进行Base64编码 3."Basic空格"拼接 二、代码示例 string authorization $"{userName}:{password}"; var authorizat…

Vue项目页面跳转时候的,浏览器窗口上方的进度条显示

1.安装&#xff1a; cnpm install --save nprogress 2.在main.js中引入&#xff1a; 1 import NProgress from nprogress 2 import nprogress/nprogress.css 3.在main.js中进行配置&#xff1a; 1 NProgress.configure({ 2 easing: ease, // 动画方式 3 spee…

使用Spring跟踪应用程序异常

几周前&#xff0c;一位同事要求我花一个星期的时间做后援&#xff0c;因为他需要一个掩护&#xff0c;而他度过了一个赚钱的假期&#xff0c;而他找不到其他人。 当我刚完成一个特别复杂的编码项目并感到有些疲倦时&#xff0c;我说“是”。 毕竟&#xff0c;改变对我有好处。…

php redis.dll php5.6,在Windows 64位下为PHP5.6.14安装redis扩展

一.php安装redis扩展1.使用phpinfo()查看当前版本的信息2.根据PHP版本号&#xff0c;编译器版本号和CPU架构选择php_redis-2.2.5-5.6-nts-vc11-x64.zip和php_igbinary-1.2.1-5.5-nts-vc11-x64.zip下载地址&#xff1a;http://windows.php.net/downloads/pecl/snaps/redis/2.2.5…

js sort方法根据数组中对象的某一个属性值进行排序(实用方法)

js sort方法根据数组中对象的某一个属性值进行排序 sort方法接收一个函数作为参数&#xff0c;这里嵌套一层函数用来接收对象属性名&#xff0c;其他部分代码与正常使用sort方法相同. var arr [{name:zopp,age:0},{name:gpp,age:18},{name:yjj,age:8} ];function compare(pr…

洛谷 P1018乘积最大

题目描述 今年是国际数学联盟确定的“20002000――世界数学年”&#xff0c;又恰逢我国著名数学家华罗庚先生诞辰9090周年。在华罗庚先生的家乡江苏金坛&#xff0c;组织了一场别开生面的数学智力竞赛的活动&#xff0c;你的一个好朋友XZXZ也有幸得以参加。活动中&#xff0c;主…

matrix derivatives

来源&#xff1a;cs229 stanford Machine Learning Notes转载于:https://www.cnblogs.com/pertinencec/p/10082965.html

Project Student:维护Webapp(只读)

这是Project Student的一部分。 其他职位包括带有Jersey的 Web服务 客户端&#xff0c;带有Jersey的 Web服务服务器 &#xff0c; 业务层 &#xff0c; 具有Spring数据的持久性 &#xff0c;分片集成测试数据 &#xff0c; Webservice集成和JPA标准查询 。 当我开始这个项目时…

基于vue的无缝滚动组件

vue-seamless-scroll A simple, Seamless scrolling for Vue.js 在awesome上一直没有发现vue的无缝滚动组件&#xff0c;在工作之余写了个组件&#xff0c;分享出来希望大家一起学习进步。Demo https://github.com/chenxuan0000/vue-seamless-scroll/index.html Installatio…

教务管理及教材订购系统设计文档

教务管理及教材订购系统设计文档目录 一、概述 1.1 开发背景 1.2 使用技术 1.3运行环境 1.4 设计目标 1.4.1权限管理 1.4.2信息管理 1.4.3选课管理 1.4.4 成绩管理 1.4.5教材订购 二、功能分析划分 2.1信息管理 2.1.1班级信息管理 2.1.2专业信息管理 2.1.3课程信息管理 2.1.4学…

关于构造器中的super()

1、为什么在子类的constructor里面要加一句super&#xff08;&#xff09;&#xff1f; 答&#xff1a;如果子类用了extends的关键字继承的父类&#xff0c;那么子类在使用构造器的时候就要加super&#xff08;&#xff09;语句&#xff0c;这是语法规范&#xff0c;就是这么定…

php 复制行,phpstorm怎么快速复制当前行?

qq_花开花谢_0PhpStorm 默认快捷键ctrlj 插入活动代码提示ctrlaltt 当前位置插入环绕代码altinsert 生成代码菜单Shift Enter 新一行ctrlq 查看代码注释ctrld 复制当前行ctrly 删除当前行ctrlalty 刷新项目缓…

Project Student:维护Webapp(可编辑)

这是Project Student的一部分。 其他帖子包括带有Jersey的 Web服务 客户端&#xff0c;带有Jersey的 Web服务服务器 &#xff0c; 业务层 &#xff0c; 具有Spring数据的持久性 &#xff0c;分片集成测试数据 &#xff0c; Webservice集成 &#xff0c; JPA标准查询和维护Webap…

express接受get数据

server.use(/,function(req,res){res.writeHead(200, { content-type:text/html;charsetutf-8});var namereq.query[name]; //直接req.query[参数名称]&#xff1b;var pwdreq.query[pwd];if(!users[name]){res.write("不存在该用户");}else if(users[name]!pwd){re…

php curl 采集文件,curl获取远程文件内容

/**获取远程文件内容param $url 文件http地址*/function fopen_url($url){if (function_exists(file_get_contents)) {$file_content file_get_contents($url);} elseif (ini_get(allow_url_fopen) && ($file fopen($url, rb))){$i 0;while (!feof($file) &&…

SAP work process Memory allocate

SAP work process Memory allocate Memory allocation sequence to dialog work processes in SAP What is the memory allocation sequence to dialog work processes in SAP?When does a work process go to PRIV mode?How to avoid or minimize work process going to PRI…

基于 Vue.js 的移动端组件库mint-ui实现无限滚动加载更多

通过多次爬坑&#xff0c;发现了这些监听滚动来加载更多的组件的共同点&#xff0c; 因为这些加载更多的方法是绑定在需要加载更多的内容的元素上的&#xff0c; 所以是进入页面则直接触发一次&#xff0c;当监听到滚动事件之后&#xff0c;继续加载更多&#xff0c; 所以对…

创建Maven源代码和Javadoc工件

许多人都知道Maven源代码和Javadoc工件&#xff0c;但是不知道为什么要创建它们。 我肯定在这个阵营中–我可以理解为什么人们想要此信息&#xff0c;但是由于要手动导航Maven存储库&#xff0c;因此获取信息似乎相对效率较低。 然后我被线索棒击中。 这些工件由IDE而非人员使…

JS内置方法(object)

属性 constructorprototype 实例方法 1、toString()返回当前对象的字符串形式&#xff0c;返回值为String类型。 2、toLocaleString()返回当前对象的"本地化"字符串形式&#xff0c;以便于当前环境的用户辨识和使用&#xff0c;返回值为String类型。 3、valueOf()返回…