設計模式與 Clean Code
涵蓋概念:Design Patterns、Clean Code
1. Design Patterns(設計模式)
設計模式是社群針對常見問題累積出的公認好解法,是工程師之間溝通的共通語言。
Module Pattern
const counterModule = (() => {
let count = 0; // 私有變數(閉包)
return { increment: () => ++count, reset: () => (count = 0) };
})();
Singleton Pattern:整個應用只存在一份實例
class Settings {
static #instance;
constructor() {
if (Settings.#instance) return Settings.#instance;
this.theme = "dark";
Settings.#instance = this;
}
}
// React Context、Redux store 精神上類似這個概念
Observer Pattern:訂閱-通知機制(超重要!)
class EventEmitter {
#listeners = new Map(); // 用 Map 而非一般物件,避免事件名稱撞到 toString、constructor 等繼承屬性
on = (name, cb) => {
if (!this.#listeners.has(name)) this.#listeners.set(name, []);
this.#listeners.get(name).push(cb);
};
emit = (name, data) => this.#listeners.get(name)?.forEach((cb) => cb(data));
}
這是 DOM 事件(
addEventListener)、Node.js EventEmitter、ReactuseState背後的核心思想:一個事件觸發,多個訂閱者都能收到通知。
Factory Pattern
const createButton = (type) => {
if (type === "primary") return { color: "blue", text: "確認" };
return { color: "gray", text: "取消" };
};
Proxy Pattern:攔截並控制存取
const userProxy = new Proxy(user, {
get: (target, prop) => { console.log(`讀取 ${prop}`); return target[prop]; },
set: (target, prop, value) => {
if (prop === "age" && value < 0) return false; // 攔截驗證
target[prop] = value;
return true;
}
});
這是 Vue 3 響應式系統的核心原理:用
get追蹤依賴、用set觸發畫面更新。不用刻意「套用」設計模式,而是反過來:發現自己寫的程式碼很眼熟時,去查查有沒有現成的名字,讓團隊溝通更有效率。
2. Clean Code(乾淨程式碼)
核心精神:程式碼是寫給人看的,剛好可以被電腦執行。
有意義的命名
// const d = new Date(); const fn = (x, y) => x * y * 0.05;
// const currentDate = new Date();
const calculateTax = (price, quantity) => price * quantity * 0.05;
- 布林值:
is、has、can開頭(isLoading) - 函式:動詞開頭(
getUserData())
函式要小、只做一件事
// 一個函式做驗證+計算+更新畫面+發送 API
// 拆成小函式,各自單一職責,方便測試與重用
const isOrderValid = (order) => order?.items?.length > 0;
const calculateTotal = (items) => items.reduce((sum, i) => sum + i.price * i.quantity, 0);
DRY(Don't Repeat Yourself)
重複的邏輯抽出來共用,改一個地方就好,不用到處找有沒有漏改。
提早返回,避免深層巢狀
// 巢狀 if 一直往右縮
const getDiscount = (user) => {
if (!user) return 0;
if (!user.isMember) return 0;
if (user.points > 100) return 0.2;
return 0.1;
};
註解該寫「為什麼」,不是「做了什麼」
// 把 count 加 1
count = count + 1;
// 解釋程式碼本身看不出來的考量
// 用 requestAnimationFrame 讓動畫排在瀏覽器下一次重繪之前執行,跟畫面更新節奏同步
requestAnimationFrame(() => startAnimation());
格式一致性交給 ESLint / Prettier 自動處理,不用自己手動維護。
本篇總結
- Observer Pattern 跟 Proxy Pattern 是理解 React/Vue 框架底層設計最關鍵的兩個模式
- 不用刻意套模式,理解概念、看懂別人程式碼在做什麼更重要
- Clean Code 六大原則:有意義命名、單一職責、DRY、提早返回、寫「為什麼」的註解、格式交給工具