Getters和Setters是糟糕的OO设计?
Getters和Setters很糟糕
简单地阅读上面的文章,我发现getter和setter是糟糕的OO设计,应该避免它们反对Encapsulation和Data Hiding。 在这种情况下,如何在创建对象时避免它,以及如何将对象模型对象考虑在内。
如果需要吸气剂或固定剂,可以使用其他替代品吗?
谢谢。
吸气剂或制定者本身也不错OO设计。
糟糕的是编码实践,其中包括一个getter和一个setter,用于自动构成每个成员,是否需要getter / setter(加上公共成员不应公开) – 因为这基本上暴露了类的实现到外部世界违反信息隐藏/抽象。 有时这是由IDE自动完成的,这意味着这种做法比预期的要广泛得多。
你错过了这一点。 该文章的有效,重要部分是:
不要求您提供完成工作所需的信息; 请询问有信息的对象为您完成工作。
Java风格的getter和setter扩散是忽略这个建议的症状。
我相信在API中包含setter只有它们真的是类规范的一部分(即它与调用者的契约)。
应隐藏与内部表示相关的任何其他数据成员,我至少看到两个主要原因:
1)如果暴露内部表示,设计变更将来会出现问题,并且还需要API更改。
2)使用setter / getter公开数据成员时不要小心,这使得调用者很容易破坏类不变量。 状态不一致的对象可能会导致很难分析的错误。
不幸的是,有一些框架鼓励(有时需要)为所有内容添加setter / getter。
吸烟者和制定者本身并不坏。 不好的做法是将任何领域变为私人领域,并为所有领域提供获取者/设定者,无论如何。
是的,吸气剂和制定者是OOP中的反模式: http : //www.yegor256.com/2014/09/16/getters-and-setters-are-evil.html 。 简而言之,它们不适合面向对象的范例,因为它们鼓励您将对象视为数据结构。 这是一个重大的误解。
作为我阅读它的方式,作者认为,盲目地在场地周围放置吸气剂和制定者并不比仅仅将场地公之于众。
我相信作者认为,吸气剂和制定者应该放在稀疏的位置,并且要小心,因为OO的想法是对象应该限制他们只接触所需的东西。
我会再说一点,只说值类型应该有吸气剂。 每个值类型都应该是不可变的,并带有一个可变的构建器并具有setter。
如果您的值类型具有setter,则应在复制其他值后返回新实例。
Url.setAnchor(…)
将返回一个新的Url复制主机端口等但覆盖锚点。
您的服务类型类不需要setter(在ctor中设置它们),并且肯定字体需要getter。 您的邮件程序应该将主机/端口/等静态内容放在它的ctor中。 如果我希望发送一封电子邮件,然后我将它发送给send(),我的代码就没有理由需要知道或想要或要求主机和其他配置值。 这就说创建一个类似于以下的MailServer类是有意义的//值类型MsilServer {String host int port String username Strung password // all come ruth getters} // factory Mailer create(MailServer)
我建议你仔细阅读整篇文章,因为它提出了深思熟虑的论点和备选方案。 问题本身太开放了,你得到的答案只会是更多的意见。
吸气剂和制定者只是方法。 他们在做什么? 他们将一个领域变成一个属性,这是一个重要的区别。
字段是对象中的一些状态数据。 属性是外部可观察的特征,是对象合同的一部分。 无论是直接地还是通过吸气剂/孵化器,在整个地方喷洒物体的内脏总是一个坏主意。 设计不佳。 但提出这一点,说吸气剂和二传手总是坏的? 那只是一些没有良好品味的穷人程序员声称模糊的经验法则(他们一开始并不真正理解)是铸铁法。
就个人而言,我倾向于试图将房产保持为客户脚下不会意外变化的东西。 (类的客户端。)我将动态更改的唯一属性是他们无法写入的属性,即使这样我也会尽量避免它。 我觉得属性在很多方面都是控制客户端设置的实例行为的值,而不是类控制下的任意事物。 (这是正常的领域……)
来自文章:
什么时候访问者好吗? 首先,正如我前面所讨论的,一个方法可以根据对象实现的接口返回一个对象,因为该接口将您与实现类的更改隔离开来。 从仅提供对字段的访问的方法的意义上讲,这种方法(返回接口引用)实际上并不是“getter”。 如果更改提供程序的内部实现,则只需更改返回对象的定义以适应更改。 您仍然通过其接口保护使用该对象的外部代码。
换句话说,当必要时,可以使用getter和setter方法的接口来保持封装。 通常,为返回类型或forms参数指定接口是一种好习惯。
还有其他文章说它们是好的设计。 但答案是:getXXX和setXXX根据使用情况的好坏。 这些方法确实使很多事情变得更容易。 所以,如果有一篇文章说这是一个糟糕的设计我认为; 它只是试图对这个想法过于刻板。
这些方法的最大用途之一是在很多框架中并用作reflection机制。
所以不要完全避免使用它们,而是……明智地使用它。
谢谢阿尤斯曼
Getters和Setters是糟糕的OO设计?
只有在没有思考的情况下使
如果您要创建一个值对象来传输数据,那么它们就没问题了。
如果你正在创造一个更重要的对象,那么他们就不应该在那里。 例如,看一下ArrayList
接口* 。 你没有看到Object[] getElementData()
因为这会打破封装(某些人可能会使基础数组发脾气)。
* 我指的是类的公共接口(类定义公开的方法)
在适当的条件下,Getters / Setters非常合适。 但是,质量Get / Set是错误的。
但是,我有点困惑。 您标记了Java,但该材料并非特别针对Java(仅限示例)。 值得注意的是,在C ++中(最好用0x完成),其中许多问题都不存在。 如果你想将你的界面从long更改为int,那么在decltype,templates和auto之间这很容易实现,这就是为什么这样的结构会摇滚。 Typedef效果也很好。