封裝變數 (Encapsulate Variable)

★★★★★Draft

FromRefactoring

📚 From the Books

封裝變數 (Encapsulate Variable)Refactoring Moves

重構資料比重構函式更難——你無法只靠提取方法就把它簡化掉。封裝變數把「重組資料」這件難事,轉化成比較單純的「重組函式」:讓所有讀寫都走 getter/setter,於是你有了一個明確的落腳點,可以加驗證、監看變化,日後再從容改動資料本身。

🧠 Why It's a Problem

一個到處都能直接存取的資料,就像散在各處的許多入口——你想改它的結構、加限制,得逐一追殺每個使用點。封裝把這些入口收攏成兩個函式(讀與寫),於是你有了單一觀測點,能控制資料如何被存取與修改。物件導向鼓勵把物件資料保持私有,正是這個道理。

NOTE

真正不可變的資料不需要封裝——它無法被修改,就沒有程式碼會讀到過時值。不可變性本身就是一種強大的保障。

⚖️ Refactoring

機械步驟:① 建立讀取與寫入的封裝函式(getter/setter)→ ② 把每個直接引用改成呼叫對應函式 → ③ 測試 → ④ 收緊原變數的可見範圍(改為私有)。

前 — 裸露的資料,人人可直接讀寫
let configValue = 50;

console.log(configValue);
configValue = 100;

configValue 是個誰都能直接動的變數。想加驗證、或想觀察它何時被改,你沒有任何一個地方可以下手。

後 — 讀寫都走封裝函式
class Configuration {
  constructor() {
    this._configValue = 50;
  }

  get configValue() {
    return this._configValue;
  }

  set configValue(value) {
    this._configValue = value;
  }
}

const config = new Configuration();
console.log(config.configValue);
config.configValue = 100;

資料變成私有的 _configValue,外界只能透過 getter/setter 觸碰它。現在 setter 就是加驗證、記錄變更、觸發副作用的明確落腳點。

TIP

有了封裝之後,若要驗證,就在 setter 內加檢查;若要監看,就在 getter/setter 內記錄——重點是這些行為終於有了一個、且只有一個該放的地方。

🔑 Takeaways

✍️ My Notes

No notes yet — jot your takeaways or Q&A here.

📖 Further Reading