为什么要使用getters和setters/访问器?

时间:2022-01-15 03:25:40

Why use getters and setters/accessors?

实际上会有很多人问这个问题....尤其是它成为Coding Style中一部分的时候。

文章出自LBushkin的回答

There are actually many good reasons to consider using accessors rather than directly exposing fields of a class - beyond just the argument of encapsulation and making future changes easier.

Here are the some of the reasons I am aware of:

  • Encapsulation of behavior associated with getting or setting the property - this allows additional functionality (like validation) to be added more easily later.
  • Hiding the internal representation of the property while exposing a property using an alternative representation.
  • Insulating your public interface from change - allowing the public interface to remain constant while the implementation changes without affecting existing consumers.
  • Controlling the lifetime and memory management (disposal) semantics of the property - particularly important in non-managed memory environments (like C++ or Objective-C).
  • Providing a debugging interception point for when a property changes at runtime - debugging when and where a property changed to a particular value can be quite difficult without this in some languages.
  • Improved interoperability with libraries that are designed to operate against property getter/setters - Mocking, Serialization, and WPF come to mind.
  • Allowing inheritors to change the semantics of how the property behaves and is exposed by overriding the getter/setter methods.
  • Allowing the getter/setter to be passed around as lambda expressions rather than values.
  • Getters and setters can allow different access levels - for example the get may be public, but the set could be protected.

简单的翻译:

实际上有许多充分的理由考虑使用访问器而不是直接暴露类的字段 - 除了封装参数和使未来的更改更容易。

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

  • 对属相相关联行为的封装——这让未来添加附加功能更加容易(如验证功能)。
  • 可选择公开属性的方式,同时隐藏属性的内部表现。
  • 让公开的接口免于修改——允许公共接口在实现更改时保持不变,而不会影响现有的使用者。
  • 控制属性的生命周期和内存管理(处置)语义 - 在非托管内存环境(如C ++或Objective-C)中尤为重要。
  • 当属性在runtime中发生改变时,为它提供调试拦截点 - 在某些语言中,在调试属性时候,想定位它在什么时候,什么地方,更改为特定值可能非常困难。
  • 改进了与旨在针对属性获取器/设置器进行操作的库的可操作性 - 例如Mocking,Serialization和WPF。
  • 允许继承者通过重写getter / setter方法来更改属性的行为和语义的语义。
  • 允许getter / setter作为lambda表达式而不是值传递。
  • getter和setter可以允许不同的访问级别 - 例如get可以是公共的,但是set可以受到保护。