是否总是使用get和set方法来访问类自己的成员字段?

在Java类中,使用getter和setter访问成员字段是不是很好或者不好?

比如哪个更好:

public Order { private Agreement agreement; public Agreement getAgreement() { return agreement; } public void process() { //should I use: getAgreement().doSomething(); //Or: agreement.doSomething(); } } 

一般来说,我认为直接访问该字段最好是由于KISS原则,并且有人可能会在以后使用不可预测的结果覆盖get方法。

然而,我的同事认为保留一层抽象更好。 对此有何共识?

这里的核心问题是直接字段访问不适合通过子类重写方法,AOP,动态代理等进行拦截。 根据具体情况,这可能是好事也可能是坏事。 我会说在内部使用getter和setter不是反模式或模式。 根据情况和class级设计,这是好事还是坏事。

老实说,在我看来,这取决于你使用它的原因。 就个人而言,如果有疑问,我总是在那里留下额外的抽象级别,以防我以后需要在子类中覆盖它。 很多时候,我只是因为我让一个吸气剂或者一个二传手打开而无法改写课程,从而避免了重写课程的痛苦。

另一件事是其他客户端/程序员可能需要以您尚未想到的方式使用您的类,例如,将Agreement类从数据库中拉出来。 在这种情况下,当他们覆盖你的类时,你已经让他们(或者可能是未来的你)无法修改数据的检索方式。

因此,除非您完全确定只有一种方法可以访问该字段,并且它是100%直接的,否则最好将值的检索和修改分离,以便在将来某一点上您可以避免重写困难。

我认为类的公共接口表示围绕状态的封装,因此即使该类的其他工作也受益于该封装。

如果你在一个公共get方法中包装了一个字段,那么你就有理由这样做了。 也许在该方法中存在惰性加载字段或提供审计跟踪的逻辑。 无论该方法的原因是什么,您的class级也很可能也需要这种逻辑。

听起来像有些人正在将这个问题解释为关于外部使用的吸气剂和制定者; 我对Pablojim的问题的解释是,它是关于在类中使用它们,而不是直接访问其字段的类。 (哪些是私人的。)

从那时起,我就和Jherico和patros在一起; 除非有某些理由不这样做,否则从课堂内直接访问。

在Java中保持一层抽象是一件好事。

问题是所有直接访问你的成员变量但没有注意到它的类的代码都不在你的类的控制之下。

因此,当您决定以一个分区中使用的一个成员作为示例永远不应该为0的方式编辑您的类时,您必须能够确保仅以确保此方式的方式更改此值。 因此,您将为此方法添加一个setter,并将该成员更改为private。 但是现在你需要在没有setter的情况下更改访问成员的所有代码。
如果您知道要从类外部更改值,并且只有在您不知道将变量设为私有时才提供setter,如果您以后需要访问,则可以提供getter或setter。

如果其他对象中的某些方法总是使用get作为成员然后执行某些计算然后使用get,则它会获得反模式。 这表明该成员应该在另一个类中,或者该方法需要在此类中。

拥有一个getter和一个setter而不考虑每个成员的内容会打破封装并且不是一个好的设计选择。 对于mor insides,请阅读本文

我现在正致力于让我更喜欢吸气剂:我们现在将部分属性转移到“属性包”中,这意味着您不能仅仅引用变量。 因此,除了更改getter之外,我们还需要更改引用该变量的所有位置。 这是要记住的事情。

这取决于你使用getter和setter的用途。 通常我会在需要检查数据进入类或格式化数据时使用它们。 在这方面,我真的使用getter和setter作为此类与可能需要访问其数据的其他类之间的接口层。

我倾向于编写我的内部代码,以便它知道如何处理这个类的私有数据,因此通过自己的getter和setter访问它通常是不必要的和不受欢迎的。

这完全取决于你如何使用你的getter和setter。

我的经验法则是,如果他们做的事情比设置或返回值更复杂,请使用setter / getters。 否则,不需要它,因为您可以修复由成员变量更改引起的任何问题。

你是对的,为每个属性变量做额外的工作都很烦人。 为什么语言允许一些基本没有人做的事情? 但是,不允许直接属性访问有非常令人信服的理由。

我更喜欢埃菲尔的统一访问原则。 您永远不能分配属性,并且以相同的方式访问属性和函数:

 class EXAMPLE feature variable: INTEGER variable_function: INTEGER do result := 4 end variable_two: INTEGER assign variable_assign variable_assign (in: INTEGER) do variable_two := in end end feature test local test: EXAMPLE value: INTEGER do create test value := test.variable -- Valid value := test.variable_function -- Valid and same even though it's a function test.variable := value -- Invalid test.variable_two := value -- Valid, an explicit setter is defined end 

我认为这是需要根据具体情况考虑的事情。 在整个类代码中使用getter会使它复杂化,并且可能会使它稍慢。 但是,它也使它更具可扩展性和可重用性。

我通常所做的就是使用吸气剂,如果我能预见到有人可能想要用另一个吸引我的吸气剂。 如果它是如此基本和简单的东西,它永远不会有意义,我通常不使用getter。

如果您编写代码以在没有getter的情况下访问变量,请考虑将getter函数设置为“final”。 这样,没有人会试图覆盖你的代码并撕掉他的头发,想知道为什么它不起作用。 (请注意,Spring和Hibernate代理可能会让这个想法变坏。)

为了使它成为一种反模式,它必须是非常有害的。 我没有看到定义getter和setter可能会有什么坏处。 最多是浪费时间(和打字),这使得它毫无意义,但不是反模式。