为什么使用getter和setter / accessors?

使用getter和setter的好处是 - 只有get和set - 而不是简单地为这些变量使用公共字段?

如果吸气人员和安装人员做的不仅仅是简单的get / set,我可以很快地把这个问题弄清楚,但是我并不十分清楚:

public String foo;

比以下任何更糟糕的是

private String foo;
public void setFoo(String foo) { this.foo = foo; }
public String getFoo() { return foo; }

而前者采用的是更少的样板代码。


实际上有许多好的理由要考虑使用访问器,而不是直接暴露一个类的字段 - 不仅仅是封装的参数,而且使未来的变化更容易。

以下是我所知道的一些原因:

  • 封装与获取或设置属性相关的行为 - 这允许稍后更容易地添加附加功能(如验证)。
  • 隐藏属性的内部表示,同时使用替代表示形式公开属性。
  • 将您的公共接口与变化隔离开来 - 允许公共接口在实现发生变化时保持不变,而不会影响现有用户。
  • 控制属性的生命周期和内存管理(处置)语义 - 在非托管内存环境(如C ++或Objective-C)中尤为重要。
  • 为属性在运行时更改时提供调试拦截点 - 在某些语言中调试何时何地属性更改为特定值可能非常困难。
  • 提高与设计为针对属性获取器/设置器进行操作的库的互操作性 - 想到模拟,序列化和WPF。
  • 允许继承者通过重写getter / setter方法来改变属性的行为语义。
  • 允许getter / setter作为lambda表达式传递,而不是值。
  • 吸气者和吸引者可以允许不同的访问级别 - 例如get可能是公开的,但该组可以被保护。

  • 由于2周(月,年)从现在开始,当你意识到你的制定者需要的不仅仅是设置的值做 ,你也意识到,财产已经在其他238类直接使用:-)


    公共领域并不比一个getter / setter对更糟糕,除了返回字段并赋值给它外。 首先,很明显(在大多数语言中)没有功能差异。 任何差异必须在其他因素,如可维护性或可读性。

    getter / setter对的一个优点是,不是。 有这个说法,你可以改变实现,你的客户不必重新编译。 据推测,setter让你稍后添加验证功能,你的客户甚至不需要知道它。 然而,向制定者添加验证是对其先决条件的改变, 违反了先前的合同 ,这很简单,“你可以在这里放置任何东西,并且可以从获得者那里得到同样的东西”。

    所以,现在你破坏了合约,改变代码库中的每个文件都是你应该做的事情,而不是避免。 如果你避开它,你就会假设所有代码都假定这些方法的合同是不同的。

    如果这不应该是合同,那么界面允许客户将对象置于无效状态。 这与封装完全相反如果这个领域从一开始就不能真正被设置为任何东西,为什么不从一开始就进行验证呢?

    这个相同的论点也适用于这些传递的getter / setter对的其他优点:如果您稍后决定更改设置的值,那么您违反了合同。 如果您在派生类中重写默认功能(超过一些无害修改(如日志记录或其他非可观察行为)),那么您将违反基类的合同。 这违反了Liskov可替代性原则,这被视为面向对象的原则之一。

    如果一个班级在每个领域都有这些愚蠢的getter和setter,那么它就是一个没有任何约束的班级,没有任何合同。 那真的是面向对象的设计吗? 如果所有班级都有那些获取者和设置者,那只是一个哑数据持有者,而哑数据持有者应该看起来像哑数据持有者:

    class Foo {
    public:
        int DaysLeft;
        int ContestantNumber;
    };
    

    将pass-through getter / setter对添加到这样的类不会增加任何值。 其他类应该提供有意义的操作,而不仅仅是字段已经提供的操作。 这就是你如何定义和维护有用的不变量。

    客户 :“我能用这个班级的对象做什么?”
    设计师 :“你可以读写几个变量。”
    客户 :“哦,很酷,我猜?”

    有理由使用getter和setter,但如果这些原因不存在,以假封装神的名义制作getter / setter对并不是一件好事。 有效的理由使得获得者或设置者包括经常提到的事情,因为后面可能会做出的变化,比如验证或不同的内部表示。 或者,也许值应该是客户可读的,但不可写(例如,阅读字典的大小),所以一个简单的getter是一个不错的选择。 但是当你做出选择时,这些原因应该在那里,而不仅仅是你以后可能想要的潜在事情。 这是YAGNI的一个例子(你不会需要它)。

    链接地址: http://www.djcxy.com/p/9131.html

    上一篇: Why use getters and setters/accessors?

    下一篇: Prefer composition over inheritance?