关于c#:Getters和Setters是不好的OO设计?

Getters and Setters are bad OO design?

本问题已经有最佳答案,请猛点这里访问。

getter和setter不好

简单地阅读上面的文章,我发现getter和setter是糟糕的OO设计,应该避免使用它们,因为它们不利于封装和数据隐藏。既然是这样,在创建对象时如何避免,以及一个模型对象如何考虑到这一点。

在需要getter或setter的情况下,可以使用其他哪些替代方法?

谢谢。


你错过了要点。这篇文章的有效的、重要的一点是:

Don't ask for the information you need
to do the work; ask the object that
has the information to do the work for
you.

Java风格的吸气剂和定位器扩散是忽略这个建议的症状。


getter或setter本身并不是糟糕的OO设计。

糟糕的是,编码实践包括自动为每个成员提供一个getter和一个setter,无论是否需要该getter/setter(加上使成员公开,但不应公开),因为这基本上会将类的实现暴露给违反信息隐藏/抽象的外部世界。有时,这是由IDE自动完成的,这意味着这种实践比预期的要广泛得多。


我相信只有当setter确实是类规范(即它与调用者的契约)的一部分时,才在API中包含setter。

任何其他与内部表示相关的数据成员都应该隐藏起来,我认为至少有两个主要原因:

1)如果暴露了内部表示,那么设计变更在将来会更加有问题,并且也需要API变更。

2)使用setter/getter公开数据成员时不必担心,这样调用方就很容易破坏类不变量。状态不一致的对象会导致非常难以分析的错误。

不幸的是,有些框架鼓励(有时需要)为所有内容添加setter/getter。


Yes,getters and setters is an anti-pattern in OOP:http://www.yegor256.com/2014/09/16/getters-and-setters-are-evil.html.在一个努茨赫尔,他们不把面向对象的范例化,因为他们鼓励你像数据结构那样对待一个对象。这是一个主要的错误。


Getters and Setters are not bad by themselves.什么是坏的做法,使任何一个领域都是私人的,并为所有这些人/定居者提供无关紧要的东西。


在我读它的时候,作者认为盲目地将getter和setter放在字段周围并不比将字段公开要好。

我相信作者认为getter和setter应该放在稀疏的地方,并且要小心,因为oo的概念是对象应该只暴露在需要的地方。


我会进一步说,只有值类型应该有getter。每个值类型都应该是不可变的,并且带有一个可变的、具有setter的生成器。

如果您的值类型具有setter,那么它们应该在复制其他值之后返回一个新实例。

url.setanchor(…)

将返回一个新的URL,复制主机端口等,但覆盖锚。

您的服务类型类不需要setter(在ctor中设置它们),字体当然需要getter。您的邮件发送者应该将主机/端口/etc静态内容放在其ctor中。如果我想发送一封电子邮件,那么我将它设为send(),没有理由让我的代码需要知道、想要或需要主机和其他配置值。也就是说,像下面这样创建一个邮件服务器类是有意义的//值类型MsServer {字符串主机INT端口字符串用户名串密码//都来了露丝·盖特}/工厂邮件创建(邮件服务器)


Getters and Setters are just methods.他们在做什么?他们把一块土地变成一块财产,这是一个重要的区别。

一个场是数据位,状态位,在对象中。财产是一种外在可观察的特性,是物体合同的一部分。把一个物体的枪口洒在地上,无论是直接地还是通过买主/买主,都是一个坏主意。贫困设计但是,让人相信,从一开始就说,getters and setters are always bad?这只是一个穷人的程序员,没有一种良好的品味要求,一个模糊的雷管(他们在第一个位置上根本不了解这一点)是一种铸铁法。

个人而言,我倾向于尝试保持财产作为不改变客户脚下的意外事物。(clients of the class that is.)The only properties that I'll change monically are one they can't write,and even then I'll try to avoid i t.我感觉到,财产在许多方面是价值,控制了客户设定的诉讼程序的行为,而不是等级控制下的仲裁事项。这是正常的地形


我建议你仔细阅读整篇文章,因为它提出了经过深思熟虑的论点和备选方案。这个问题本身太开放了,你在这里得到的答案将只是更多的意见。


Getters/Setters are perfectly appropriate,in the right conditions.但是,大批人都错了。

但是我有点困惑You tagged Java,but the material isn't really particularly Java specific(only the examples).值得注意的是,在C+(最好在0X)中,许多问题不存在。如果你想从长远到长远改变你的界面,那么从解剖型,模板和汽车之间的界面,这是很容易实现的,这就是为什么如此的结构摇滚。Typedef works well too.


Getters and Setters are bad OO design?

只有在没有思考的情况下才使用。

如果你要创建一个输送数据的价值-目标,他们会很好。

如果你创造了一个更重要的目标,他们就不应该在这里。看着ArrayList界面*用于实例。你看不到Object[] getElementData()因为这会打破封装(有人可能会使底部阵列更长)。

*im referring to the public interface of the class(the methods exposed by the class definition)


还有其他文章说它们设计得很好。但答案是:根据用法,getxxx和setxxx是好的还是坏的。这些数学确实使很多事情变得容易。所以,如果有文章说这是一个糟糕的设计,我想,这只是试图在这个想法太难了。

这些方法的最大用途之一是在许多框架中,并用作反射机制。

所以不要完全避免使用这些,而是…明智地使用它。

谢谢阿尤斯曼


从文章中:

When is an accessor okay? First, as I
discussed earlier, it's okay for a
method to return an object in terms of
an interface that the object
implements because that interface
isolates you from changes to the
implementing class. This sort of
method (that returns an interface
reference) is not really a"getter" in
the sense of a method that just
provides access to a field. If you
change the provider's internal
implementation, you just change the
returned object's definition to
accommodate the changes. You still
protect the external code that uses
the object through its interface.

换句话说,当getter和setter方法需要时,可以使用它们的接口来维护封装。通常,为返回类型或形参指定接口是一种良好的实践。