一個變數頻繁被改動、而且作用域又大,就等於埋了一顆地雷:某處的一次修改,會在你意想不到的地方引爆。解法是把「誰能改、怎麼改」收攏起來——封裝變數、把查詢與修改分離、限制變動範圍。
🧠 Why It's a Problem
- 改動難以追蹤:變數頻繁變動時,很難掌握它在某個時刻到底是什麼值、又是被誰改的。
- 作用域太大:可被改動的地方越多,出錯的面就越廣;本章把它歸在資料與變數管理——資料的範圍與型態管理不當,是導致系統脆弱的主因。
- 查詢與修改糾纏:讀一個值的同時順手改了它,讓副作用藏在看似無害的存取裡。
NOTE
對應重構是封裝變數(Encapsulate Variable),把資料藏到存取函式後面,並且把查詢與修改分離,讓每一次改動都經過同一道收斂的入口。
⚖️ Refactoring
Encapsulate Variable:讓變數只能透過存取函式被讀寫,改動點就從「到處」收斂成「一處」。
前 — 作用域大、到處直接改
let discount = 0;
function applyPromo() {
discount = 0.2;
}
function render() {
// 讀 discount 的同時又順手改了它
if (discount === 0) discount = 0.05;
return `折扣:${discount}`;
}discount 誰都能改、隨處在變,render 甚至在「查詢」時偷偷改了值——某天的 bug 幾乎無法回推是哪一次改動造成的。
後 — 封裝變數,並把查詢與修改分離
let discount = 0;
function getDiscount() {
return discount;
}
function setDiscount(value) {
discount = value;
}
function applyPromo() {
setDiscount(0.2);
}
function render() {
return `折扣:${getDiscount()}`;
}改動只能經過 setDiscount 一道入口;render 只查詢、不再修改。變動範圍被限制住,值的每一次變化都有跡可循。
TIP
「查詢不改狀態、修改不回傳值」就是命令與查詢分離:把兩者拆開,讀取才安全、副作用才顯眼。
🔑 Takeaways
- 可變資料的訊號是變數頻繁變動、而且作用域大——改動難追蹤,bug 難回推。
- 標準解是封裝變數:把資料藏到存取函式後面,讓改動點收斂成一處。
- 再把查詢與修改分離,並限制變動範圍,讓每次改動都經過同一道入口、都有跡可循。
No notes yet — jot your takeaways or Q&A here.