accessors 小註解

accessors 指的是物件導向語言裡面的 accessor methods. 根據 [1], 它是用來返回或設定 private field 的值. 取值的時候用 get 開頭的  method (getter), 像是 public String getLotteryNumber(). 設值的時候用 set 開頭的 method (setter), 像是 public String setMyBankAccount(), 此時稱之為 mutators. 但的確也有人把 get 和 set 都混稱為 accessors [2], 所以我也就以一當二, 省掉一些文字.

顯然地, accessors 是用 public 的方法去影響 private field. 正常來說, 在使用者無感的情況下, 它可以做到 [1]:

  • change how the data is handled behind the scenes, 像是改變 method 的定義.
  • impose validation on the values that the fields are being set to, 像是修改 data 的值域.

當然, 這就造成了反對者的批判.  [Ref 2] 的作者 Allen Holub 認為, 如果需要修改 type 等等, 只需要在特定的地方操作, 不需要有個 method 把幾百幾千個 call accessors 的地方都暴露在危險之中. 故 accessors 違背了物件導向封裝的原則.

What if you need to change the accessed field's type? You also have to change the accessor's return type. You use this return value in numerous places, so you must also change all of that code. I want to limit the effects of a change to a single class definition. I don't want them to ripple out into the entire program.

Since accessors violate the encapsulation principle,…

比較不那麼義正辭嚴, 相對搞笑的批評是這個 [3], 他有十大理由使用 setter 和 getter, 但是怎麼看都有點明褒暗貶.

  1. When you realize you need to do more than just set and get the value, you don't have to change every file in the codebase.
  2. You can perform validation here.
  3. You can change the value being set.
  4. You can hide the internal representation. getAddress() could actually be getting several fields for you.
  5. You've insulated your public interface from changes under the sheets.
  6. Some libraries expect this. Reflection, serialization, mock objects.
  7. Inheriting this class, you can override default functionality.
  8. You can have different access levels for getter and setter.
  9. Lazy loading.
  10. People can easily tell you didn't use Python.

​不管正反意見如何, 總之 C#, Action Script, Javascript 都可以用 accessors. 當我們以 Javascript 寫在 HTML 裡面時, 比較沒有被陌生人引用的風險, 相對地好處較為明顯. 但 Javascript 1.8.1 開始, 硬是限制了 setter 的用法 [Ref 5,6], 而 getter 只是取值而已故不受影響.這大概是 2008 年的事.因為我正在讀的 "新書" 裡面有提到 setter/getter, 所以幫它考證一下.

{{ js_minversion_note("1.8.1", "自 JavaScript 1.8.1 起,在設定物件和陣列裡的初始化子的屬性時,不再可以呼叫 Setter。") }}

Starting in JavaScript 1.8.1, setters are no longer called when setting properties in object and array initializers.

[ref]

1. Accessors and Mutators

2. Why getter and setter methods are evil

3. Why use getters and setters?

4. Javascript Getters and Setters for localStorage

5. Getter 和 Setter 的定義

6. set