我們在 JavaScript 中真正使用的 5 大設計模式 | 高級 JS/TS
在前端開發的廣闊領域中,設計模式猶如一把萬能鑰匙,能夠解鎖眾多常見的編程難題。本文將深入探討JavaScript中最實用、最受歡迎的五種設計模式,這些模式不僅能提高代碼的可維護性和可擴展性,還能讓代碼結構更加清晰。
1.單例模式:全局唯一的守護者
單例模式確保一個類僅有一個實例,并提供一個訪問它的全局節點。這種模式在管理全局狀態時尤其有效,比如處理應用配置、日志記錄或緩存機制。
class ConfigManager {
constructor() {
if (ConfigManager.instance) {
return ConfigManager.instance;
}
this.config = {};
ConfigManager.instance = this;
}
setConfig(key, value) {
this.config[key] = value;
}
getConfig(key) {
return this.config[key];
}
}
const config1 = new ConfigManager();
const config2 = new ConfigManager();
console.log(config1 === config2); // 輸出: true
在需要管理全局狀態(如管理配置、日志或緩存)的情況下,單例模式至關重要。
2. 觀察者模式:事件驅動的核心
觀察者模式允許對象(主題)維護一系列依賴于它的對象(觀察者),并在狀態發生變化時通知它們。這種模式在構建響應式用戶界面和實時系統時特別有用。
class NewsPublisher {
constructor() {
this.subscribers = [];
}
subscribe(observer) {
this.subscribers.push(observer);
}
unsubscribe(observer) {
this.subscribers = this.subscribers.filter(sub => sub !== observer);
}
notifyAll(news) {
this.subscribers.forEach(sub => sub.update(news));
}
publishNews(news) {
this.notifyAll(news);
}
}
class NewsSubscriber {
constructor(name) {
this.name = name;
}
update(news) {
console.log(`${this.name} 收到新聞: ${news}`);
}
}
const publisher = new NewsPublisher();
const sub1 = new NewsSubscriber('訂閱者A');
const sub2 = new NewsSubscriber('訂閱者B');
publisher.subscribe(sub1);
publisher.subscribe(sub2);
publisher.publishNews('重大突發新聞!');
觀察者模式對于構建可擴展的模塊化應用程序至關重要,尤其是在處理用戶界面和實時系統時。
3. 工廠模式:對象創建的智能工廠
工廠模式提供了一個用于創建對象的接口,而無需指定將要創建的對象的確切類。這種模式在處理復雜對象創建邏輯時特別有用。
class VehicleFactory {
createVehicle(type) {
switch(type) {
case 'car':
return new Car();
case 'bike':
return new Bike();
default:
throw new Error('未知的車輛類型');
}
}
}
class Car {
drive() {
console.log('駕駛汽車');
}
}
class Bike {
ride() {
console.log('騎自行車');
}
}
const factory = new VehicleFactory();
const car = factory.createVehicle('car');
const bike = factory.createVehicle('bike');
car.drive();
bike.ride();
工廠模式簡化了對象的創建,使代碼更靈活,更易于擴展。
4. 模塊模式:代碼組織的藝術
模塊模式用于封裝相關的函數、變量和類到一個單獨的單元中,提供了更清晰、更模塊化的代碼庫。這種模式在JavaScript中特別有用,可以有效管理作用域并防止全局命名空間污染。
const Calculator = (function() {
let result = 0;
return {
add: function(x) {
result += x;
},
subtract: function(x) {
result -= x;
},
getResult: function() {
return result;
}
};
})();
Calculator.add(5);
Calculator.subtract(2);
console.log(Calculator.getResult()); // 輸出: 3
模塊模式對于創建獨立的代碼單元至關重要,這些單元可以很容易地重復使用和維護。
5. 裝飾器模式:動態功能擴展
裝飾器模式允許動態地向個別對象添加行為,而不影響同類中其他對象的行為。這種模式為擴展功能提供了一種靈活且可重用的方式。
class Coffee {
cost() {
return 5;
}
description() {
return '普通咖啡';
}
}
function milkDecorator(coffee) {
const cost = coffee.cost();
const description = coffee.description();
coffee.cost = () => cost + 2;
coffee.description = () => `${description}, 加牛奶`;
return coffee;
}
function sugarDecorator(coffee) {
const cost = coffee.cost();
const description = coffee.description();
coffee.cost = () => cost + 1;
coffee.description = () => `${description}, 加糖`;
return coffee;
}
let myCoffee = new Coffee();
myCoffee = milkDecorator(myCoffee);
myCoffee = sugarDecorator(myCoffee);
console.log(myCoffee.description()); // 輸出: 普通咖啡, 加牛奶, 加糖
console.log(myCoffee.cost()); // 輸出: 8
裝飾器模式為擴展功能提供了一種靈活的子類化替代方式,使修改行為變得更加容易,而無需改變現有的代碼庫。
結語
這五種設計模式——單例、觀察者、工廠、模塊和裝飾器——在JavaScript生態系統中極其實用。它們為常見問題提供了強大的解決方案,使代碼更易于維護、擴展和理解。
雖然在一般編程中存在20多種設計模式,但這五種是日常JavaScript開發中最常用到的。掌握這些模式,將極大地提升我們的代碼質量和開發效率。