© 2024 Merano Tu. All rights reserved.
Merano Tu
2025/3/4
這裡是一些常見的前端設計模式(Design Patterns),並提供實際使用的例子來說明它們在前端開發中的應用。
這些設計模式主要用於解決常見的前端問題,提升代碼的結構化、可維護性和可擴展性。
以下是幾個主要的設計模式及其應用:
=> 封裝公有私有
模塊模式通過封裝邏輯,將私有變量和方法與公開的API分離,減少全局命名空間的污染。
假設你正在開發一個計數器功能:
const Counter = (function () {
let count = 0; // 私有變量
return {
increment: function () {
count++;
console.log(count);
},
decrement: function () {
count--;
console.log(count);
},
getCount: function () {
return count;
}
};
})();
Counter.increment(); // 1
Counter.increment(); // 2
Counter.decrement(); // 1
console.log(Counter.getCount()); // 1
在這個例子中,count 是私有的,外部只能通過公開的方法來操作計數器。
=>事件監聽、訂閱
觀察者模式定義了一個對象(主題)與多個觀察者之間的依賴關係,當主題狀態改變時,所有觀察者會自動收到通知。
一個簡單的事件訂閱與發布系統:
class EventEmitter {
constructor() {
this.listeners = {};
}
on(event, callback) {
if (!this.listeners[event]) {
this.listeners[event] = [];
}
this.listeners[event].push(callback);
}
emit(event, data) {
if (this.listeners[event]) {
this.listeners[event].forEach(callback => callback(data));
}
}
}
const emitter = new EventEmitter();
emitter.on('click', (data) => console.log(`Clicked: ${data}`));
emitter.emit('click', 'Button 1'); // 輸出: Clicked: Button 1
在實際應用中,這可以用於監聽用戶交互,例如點擊按鈕後觸發多個回調 (callback)。
-> enum、Redux 全域狀態管理
單例模式確保一個類只有一個實例,並提供全局訪問點。
假設你需要一個全局的配置對象:
class Config {
constructor() {
if (!Config.instance) {
this.settings = { theme: 'light', lang: 'en' };
Config.instance = this;
}
return Config.instance;
}
getSetting(key) {
return this.settings[key];
}
}
const config1 = new Config();
const config2 = new Config();
console.log(config1 === config2); // true
console.log(config1.getSetting('theme')); // 'light'
這裡,不管創建多少次 Config,都只會返回同一個實例。
=> 可複用元件
工廠模式通過一個工廠函數或類來創建對象,而不需要直接使用 new 關鍵字。
假設你需要根據類型生成不同的按鈕:
class ButtonFactory {
static createButton(type) {
switch (type) {
case 'primary':
return { text: 'Primary Button', style: 'blue' };
case 'secondary':
return { text: 'Secondary Button', style: 'gray' };
default:
return { text: 'Default Button', style: 'black' };
}
}
}
const primaryBtn = ButtonFactory.createButton('primary');
console.log(primaryBtn); // { text: 'Primary Button', style: 'blue' }
在 React 中,這可以用於根據 props 動態生成組件。
裝飾者模式允許在不修改原有對象的情況下,動態地為對象添加功能。
假設你有一個發送請求的功能,想添加日誌功能:
function fetchData(url) {
console.log(`Fetching data from ${url}`);
return Promise.resolve('Data');
}
function withLogging(fetchFn) {
return function (url) {
console.log(`Log: Starting request to ${url}`);
return fetchFn(url).then(data => {
console.log(`Log: Request completed`);
return data;
});
};
}
const loggedFetch = withLogging(fetchData);
loggedFetch('https://api.example.com');
// 輸出:
// Log: Starting request to https://api.example.com
// Fetching data from https://api.example.com
// Log: Request completed
這裡,withLogging 是一個裝飾者,為 fetchData 增加了日誌功能。
MVC 將應用分成模型(數據)、視圖(UI)和控制器(邏輯)三部分。
MVC 是一種經典的設計模式,最初由 Trygve Reenskaug 在 1970 年代提出,用於 Smalltalk 系統。它的核心目標是將應用程序的邏輯分為三個相互關聯的部分,從而實現關注點分離(Separation of Concerns),提高代碼的可維護性和可擴展性。
Model(模型)
作用:負責數據的管理、業務邏輯和存儲。它是應用程序的「真相之源」(source of truth)。
職責:
例子:一個購物車的數據結構,包含商品列表、總價計算邏輯等。
View(視圖)
Controller(控制器)
這種單向數據流(View → Controller → Model → View)確保了數據與展示的清晰分離。
一個簡單的計數器應用:
// Model 模型(數據)
const model = {
count: 0,
updateCount(value) {
this.count += value;
view.render(this.count);
}
};
// View 視圖(UI)
// 跟畫面之間的互動
const view = {
render(count) {
document.getElementById('count').textContent = count;
}
};
// Controller 控制器(邏輯)
// 控制執行
const controller = {
increment() {
model.updateCount(1);
},
decrement() {
model.updateCount(-1);
}
};
// HTML: <button onclick="controller.increment()">+</button>
// <button onclick="controller.decrement()">-</button>
// <span id="count">0</span>
這些前端設計模式在實際開發中非常常見,尤其是在需要構建可擴展和可維護的應用時。以下是它們的典型應用場景總結:
與 grok 協作
相關資料:
前端也有 DESIGN PATTERNS