吸气剂/设定者。 邪恶。 期。

从2003年开始,艾伦·霍鲁布(Allen Holub)讨论了为什么吸气剂和塞特方法是邪恶的著名文章,关于吸气剂/塞特方法是否是反模式,应该避免使用,还是我们在面向对象中不可避免地需要它,这是一个古老的争论。编程。 我将在讨论中加我的两分钱。

以下是本文的要旨:吸气剂和吸气剂是一种糟糕的做法,使用它的人不能被原谅。 同样,为了避免任何误解,我并不是说应尽可能避免进行get / set操作。 不,我是说您永远不要让它们靠近您的代码。

大卫·韦斯特的物体思考 傲慢到足以引起您的注意? 您使用该获取/设置模式已有15年了,您是一位受人尊敬的Java架构师吗? 而且您不想听到陌生人的胡话吗? 好吧,我了解您的感受。 当我偶然发现David West的《 对象思维》时,我的感觉几乎是一样的。 所以,请。 冷静下来,尝试理解,而我尝试解释。

现有参数

在面向对象的世界中,有一些反对“存取器”(getter和setter的别称)的争论。 我认为所有这些都不够强大。 让我们简要地介绍一下它们。

询问,不要告诉:艾伦·霍鲁布(Allen Holub)说:“不要询问您需要做的工作; 询问具有信息的对象为您完成工作。”

违规封装原理:一个对象可以被其他对象撕裂 ,因为它们能够通过设置器将任何新数据注入该对象。 该对象根本无法足够安全地封装其自身的状态,因为任何人都可以更改它。

公开的实现细节:如果我们可以从另一个对象中获得一个对象,则说明我们过于依赖第一个对象的实现细节。 如果明天它会改变,例如,结果的类型,我们也必须改变代码。

所有这些理由都​​是合理的,但它们没有要点。

基本误解

大多数程序员认为对象是带有方法的数据结构。 我引用的是Bozhidar Bozhanov的文章《 Getters and Setters Not Evil》 :

但是,人们为其生成getter和setter的大多数对象都是简单的数据持有者。

这种误解是巨大误会的结果! 对象不是“简单的数据持有人”。 对象不是具有附加方法的数据结构。 这种“数据持有人”的概念来自于过程语言(尤其是C和COBOL)的面向对象编程。 我再说一遍:对象不是一组数据元素和操作它们的函数。 对象不是数据实体。

之后怎么样了?

球和狗

在真正的面向对象编程中,对象就是像您我一样的活物。 它们是生命有机体,具有自己的行为,特性和生命周期。

生命有机体可以有二传手吗? 你能“把”球放到狗身上吗? 并不是的。 但这正是以下软件正在执行的操作:

Dog dog = new Dog();
dog.setBall(new Ball());

听上去怎么样?

你能从狗身上得到一个球吗? 好吧,如果她吃了并且正在做手术,您可能可以。 在那种情况下,是的,我们可以从狗那里“拿走”一个球。 这就是我在说的:

Dog dog = new Dog();
Ball ball = dog.getBall();

还是一个更荒谬的例子:

Dog dog = new Dog();
dog.setWeight("23kg");

您能想象现实中的交易吗?

它看起来与您每天写的内容相似吗? 如果是,那么您就是程序程序员。 承认吧 这就是大卫·韦斯特(David West)在他的书的第30页上说的:

将成功的程序开发人员转换为成功的对象开发人员的第一步是放样。

您需要放气吗? 好吧,在阅读《西方的对象思维 》时,我肯定需要一个并收到了它。

对象思维

开始像对象一样思考,您将立即重命名那些方法。 这可能是您将得到的:

Dog dog = new Dog();
dog.take(new Ball());
Ball ball = dog.give();

现在,我们将狗当做一种真正的动物,当我们要求时,他可以从我们这里拿走球并将其还给他。 值得一提的是,狗不能退还NULL 。 狗根本不知道NULL是什么! 对象思维立即消除了代码中的NULL引用 。

查尔斯·克里顿(1988)

查尔斯·克里顿(1988)

除此之外,对象思考将导致对象的不变性,例如“狗的重量”示例。 您可以这样改写:

Dog dog = new Dog("23kg");
int weight = dog.weight();

狗是一成不变的生物,不允许外界任何人改变自己的体重,大小或名字等。她可以根据要求告知自己的体重或名字。 公共方法没有任何问题,可以证明对某个对象的某些“内部”请求。 但是这些方法不是“获取器”,它们永远不应带有“获取”前缀。 我们没有从狗身上“得到”任何东西。 我们没有得到她的名字。 我们要她告诉我们她的名字。 看到不同?

我们也不在这里谈论语义。 我们正在将过程编程的思维方式与面向对象的思维方式区分开。 在过程编程中,我们正在处理数据,在需要时对其进行处理,获取,设置和删除。 我们负责,数据只是一个被动组件。 狗对我们来说什么都不是-它只是一个“数据持有者”。 它没有自己的生活。 我们可以自由地从中获取任何必要的东西,并将任何数据放入其中。 这就是C,COBOL,Pascal和许多其他程序语言的工作方式。

相反,在一个真实的面向对象的世界中,如果您愿意的话,我们将具有生命日期和死亡时刻的生物视为具有生命本身的物体,就像它们一样。 我们可以请狗给我们一些数据(例如,她的体重),然后她可能会向我们返回该信息。 但是我们始终记得,狗是一种活跃的成分。 她决定在我们要求之后会发生什么。

这就是为什么在概念上让任何方法都以setget in object开头是不正确的 。 但这并不像许多人认为的那样破坏封装。 无论您是想像一个对象还是仍在用Java语法编写COBOL。

PS。 是的,您可能会问-JavaBeans,JPA,JAXB和许多其他依赖于get / set表示法的Java API呢? Ruby的简化了访问器创建的内置功能呢? 好吧,所有这些都是我们的不幸。 留在过程式COBOL的原始世界中,要比真正理解和欣赏真实对象的美丽世界要容易得多。

PPS。 忘了说,是的,通过setter进行依赖注入也是一种可怕的反模式。 关于它,在下一篇文章中!

相关文章

您可能还会发现以下有趣的帖子:

  • OOP中的反模式
  • 避免字符串串联
  • 对象应该是不可变的
  • 为什么NULL是错误的?
  • 实用程序类的OOP替代

翻译自: https://www.javacodegeeks.com/2014/09/getterssetters-evil-period.html

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

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

相关文章

你不可不知的数据库northwind

说起northwind,40左右的大年一定不会陌生,它是著名的northwind示例库,在SQL Server 是标配。 它有8张表,涉及客户、商品、订单。 如果你是有志从事企业级应用开发,或有志从事企业互联网开发,一定不要错过no…

angularjs中 $watch 和$on 2种监听的区别?

1.$watch简单使用 $watch是一个scope函数,用于监听模型变化,当你的模型部分发生变化时它会通知你。 $watch(watchExpression, listener, objectEquality); 每个参数的说明如下: watchExpression:监听的对象,它可以是…

【原】.Net创建Excel文件(插入数据、修改格式、生成图表)的方法

1.添加Excel引用 可以在.Net选项卡下添加Microsoft.Office.Interop.Excel引用,或在COM下添加Microsoft Excel 12.0 Object Library。它们都会生成Microsoft.Office.Interop.Excel.dll。 2.创建Excel。 有两种方法创建一个Excel Workbook实例。 1.需要一个模板文件&…

求助:安装程序无法创建一个DCOM用户帐号来注册.....\valec.exe

http://support.microsoft.com/kb/257413/ 这是Visual Studio的一个BUG,只出现在Windows 2000/XP下。如果你不使用Visual Studio Analyzer,可以在安装时选择Custom,然后在Enterprise Tools中清除掉Visual Studio Analyzer。再安…

Spring / Hibernate使用log4jdbc改进了SQL日志记录

Hibernate提供了开箱即用的SQL日志记录,但是这种日志记录仅显示准备好的语句,而不显示发送到数据库的实际SQL查询。 它还不会记录每个查询的执行时间,这对于性能故障排除很有用。 这篇博客文章将介绍如何设置Hibernate查询日志记录&#xff…

快递API接口

快递100 转载于:https://www.cnblogs.com/onesmail/p/10608600.html

js中split()和join()的用法

Split()方法:把一个字符串分割成字符串数组 如上所示:把字符串a按空格分隔,得3个字符串数组。 在如: var a”hao are you” a.split(“”); 得到[h,a,o,a,r,e,y,o,u]; Join方法: 把数组中的所有元素转换为一个字符串 如上图所…

IT行业经典面试题,121套面试题

IT行业经典面试题,121套面试题 资源大小: 580.80KB资源类型:发布人: eyelife 发布日期: 2天前Tag: 名企,计算机 资源分: 10下载人数: 857 4.33/347人评分 12 3 4 5 评论 分享…

词云第一次实践,参考学校老师讲的一些知识点还有网上大佬的代码实现

from wordcloud import WordCloudimport cv2import jiebawith open(1906月考.txt, r, encodingutf-8) as f: # 以读的方式打开词云参考的文档 text f.read() # 阅读cut_text .join(jieba.cut(text)) # 通过jieba库的cut精确模式进行分词# 得到词云形状color_mask cv2…

Spring Integration 4.0:完整的无XML示例

1.简介 Spring Integration 4.0终于发布了 ,并且此版本具有非常好的功能。 本文介绍的一种可能性是完全不使用XML即可配置集成流程。 那些不喜欢XML的人仅使用JavaConfig就可以开发集成应用程序。 本文分为以下几节: 介绍。 流程概述。 弹簧配置。 …

http协议组成(请求状态码)

http请求由:请求行;消息报头;请求正文组成 //请求行 Request URL: http://172.32.4.33:8080/operation/v2/autoServer/queryAutoServer.htm //请求地址 Request Method: POST …

CSS伪类的三种写法

今天逛蓝色时&#xff0c;无意发现了有人讨论伪类的正确写法&#xff0c;让我对伪类的认识也更清晰了&#xff0c;转贴于此&#xff0c;以备日后查询(原贴当时没记下地址&#xff0c;已经记不得了) Code<style>a.tb{text-decoration:none;}a.tb:link{color:#FF9900;}a.tb…

sql自动生成golang结构体struct实体类

废话不多说直接上地址 使用地址http://www.linkinstars.com:8090/auto-code 项目github https://github.com/LinkinStars/Auto-Coding 是上次内容的一个更新&#xff0c;方便自己用&#xff0c;希望你也喜欢https://www.cnblogs.com/linkstar/p/10037629.html &#xff08;半个…

如何通过示例在Java中使用CopyOnWriteArraySet

CopyOnWriteArraySet是CopyOnWriteArrayList类的弟弟。 这些是专用集合类&#xff0c;这些类是在JDK 1.5上添加的&#xff0c;以及它们最流行的表亲ConcurrentHashMap 。 它们是并发收集框架的一部分&#xff0c;位于java.util.concurrent包中。 CopyOnWriteArraySet最适合作为…

生成器

一、什么是生成器 通过列表生成式&#xff0c;我们可以直接创建一个列表。但是&#xff0c;受到内存限制&#xff0c;列表容量是有限的。而且&#xff0c;创建一个包含100万个元素的列表&#xff0c;不仅占用很大的存储空间&#xff0c;如果我们仅仅需要访问前面几个元素&#…

VS2008快捷键大全

CtrlmCrtro折叠所有大纲CtrlMCrtrP: 停止大纲显示CtrlKCrtrC: 注释选定内容CtrlKCrtrU: 取消选定注释内容CtrlJ : 列出成员 智能感知ShiftAltEnter: 切换全屏编辑CtrlB,T / CtrlK,K: 切换书签开关CtrlB,N / CtrlK,N: 移动到下一书签 CtrlB,P: 移动到上一书签 CtrlB,C: 清除全部…

jQuery 入口函数主要有4种写法

jqery 入口函数主要有4种写法&#xff0c;其中以第3种方法最为方便。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"…

面向对象的三大特征 封装继承多态

面向对象设计 和开发程序的好处 交流更加流畅 、提高设计和开发效率 封装将类的某些信息隐藏在类内部&#xff0c;不允许外部程序直接访问&#xff0c;而是通过该类提供的方法来实现对隐藏信息的操作和访问私有化属性 提供公有化的访问方法 保证数据的安全性封装的步骤 …

Spring / Hibernate应用程序的性能调优

对于大多数典型的Spring / Hibernate企业应用程序&#xff0c;应用程序性能几乎完全取决于其持久层的性能。 这篇文章将讨论如何确认我们是否存在“数据库绑定”应用程序&#xff0c;然后逐步讲解7个经常使用的“快速取胜”技巧&#xff0c;这些技巧可以帮助提高应用程序性能。…

我的学习开发环境,呵呵!

今天到电子市场去&#xff0c;花了近700块&#xff0c;弄了块ARM的学习单板&#xff0c;再也不用去搞什么虚拟机了&#xff01; 简单的看了一下开发手册&#xff0c;还有点麻烦&#xff0c;可能得花点时间去把它搞清楚&#xff01; 但这块单板的功能还是很强的&#xff0c;基本…