从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)

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

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

吸气剂/设定者。 邪恶。 期。相关推荐

  1. 80老翁谈人生(210):方正上市前的静默期的突发事件

    80老翁谈人生(210):方正上市前的静默期的突发事件 所谓"上市前的静默期"是指,公司在股票首日上市交易前的一段时期内或上市后的几天内对外不发布任何信息,任人评说,三缄其口,保持 ...

  2. DI容器是代码污染者

    尽管依赖项注入 (也称为" DI")是一种在OOP中组成对象的自然技术(在Martin Fowler引入该术语之前就已知道),但Spring IoC , Google Guice ...

  3. android游戏课程设计,Miuka「游戏化课程设计」图卡18|好课程如何讲故事的

    从[故事隐喻][游戏旅途][重要关卡][进化蜕变]四个维度对课程进行叙事描述. 可以利用这个思路为课程设计故事脚本,来描述学员会在课程中经历什么. 案例1:手账小行星,用了星球探索这个主题 故事设定: ...

  4. Smarty的配置与高级缓存技术

    前言 Smarty 是一个出色的PHP模板引擎,它分离了逻辑代码和user interface. 学习和使用Smarty,没有应用到它的缓存技术是一个很大的损失,它可以将用户最终看到的HMTL文件缓存 ...

  5. smarty实例教程

    一.什么是smarty? smarty是一个使用PHP写出来的模板PHP模板引擎,它提供了逻辑与外在内容的分离,简单的讲,目的就是要使用PHP程序员同美工分离,使用的程序员改变程序的逻辑内容不会影响到 ...

  6. 利用logistic回归构建申请信用评级案例

    申请评分卡对于从事信贷风控行业的人来说肯定不陌生,甚至每天都会应用到.申请评分,即对申请客户打分,对于业务专家来说可以是基于经验对客户资质进行评估,最终决定是否给予通过申请,首先基于经验的评估很难量化 ...

  7. 内省java_Java内省 – 奇怪的行为

    下面的代码是一个很容易重现问题的小例子.所以我有一个类型为String的变量,在其上设置一个默认值.我有3种方法: 吸气剂 >设定者 >方便的方法,将字符串转换为布尔值 内部回调并不返回g ...

  8. 国内手机产业混乱:产业一窝蜂 企业捞快钱

    对于当前国内手机行业的现状,本报记者采访的多位业内人士表示,目前国内手机行业仍是"红海"格局,多数企业并不了解手机产业规律,看到有钱赚就"一窝蜂"上项目.有行业 ...

  9. PHP模板引擎smarty详细介绍

    篇文章主要介绍了PHP模板引擎smarty详细介绍,本文讲解了什么是smarty.smarty优点.不适合使用smarty的地方.smarty目录结构及版本,需要的朋友可以参考下 /* 一.什么是sm ...

最新文章

  1. C++多线程之间,线程函数启动之后,多线程依赖的启动和线程唤醒操作。
  2. 阿里面试这样问:Nacos配置中心交互模型是 push 还是 pull ?(原理+源码分析)...
  3. python画直方图成绩分析-python plotly绘制直方图实例详解
  4. 怎么书写高质量jQuery代码
  5. Chipseq数据库的建立
  6. Log4j的组件和配置文件介绍
  7. spring基于XML的AOP-编写必要的代码
  8. win7电脑总是提示重新启动计算机以完成重要更新的安装是怎么回事,Win7开机时弹出Windows Update提示,怎样解决?(图文)...
  9. 清除浮动的最佳方案:clearfix
  10. mysql定时器 教程_mysql定时任务
  11. html烟火源码,HTML5:烟火
  12. JAVA作业 17-05-18
  13. 软件测试自我评价模版,软件测试简历自我评价填写样本
  14. 复旦sakai安装指南
  15. 亚马逊网上书店、巴诺书店最佳畅销书《最后期限》
  16. 这个世界上人真的分三六九等,你信吗?
  17. 大学四年就靠这些东西成为别人眼中的大神(工具用好才是硬道理,兵来将挡,水来土掩)
  18. 51单片机 ADC0832酒精传感器
  19. python绘制散点图的步骤_python绘制散点图
  20. 【视频分享】尚硅谷HTML5前端视频_Vue核心技术视频

热门文章

  1. Java连接PostgreSQL数据库,增删改查
  2. java异常—— finally 子句+带资源的 try语句
  3. spring缓存_有关Spring缓存性能的更多信息
  4. jasperreports_JasperReports:棘手的部分
  5. 面向对象代码_面向对象的代码生成方法
  6. mockito 静态_在Java 8中使用不带静态导入的Mockito
  7. 工厂模式理解_工厂模式
  8. bean注入属性_摆脱困境:将属性值注入配置Bean
  9. es 调整gc_实际中进行GC调整
  10. di容器_DI容器是代码污染者