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