JavaScript 設(shè)計(jì)模式是一種優(yōu)秀的編程思想,它可以幫助開(kāi)發(fā)者更好地組織和管理代碼。在軟件開(kāi)發(fā)中,設(shè)計(jì)模式不僅可以提高程序的可維護(hù)性和可重用性,還可以提高程序的可讀性和可擴(kuò)展性。下面我們就一起來(lái)探討一下 JavaScript 設(shè)計(jì)模式。
首先我們先來(lái)看看最常見(jiàn)的設(shè)計(jì)模式之一:?jiǎn)卫J健卫J绞且环N特殊的設(shè)計(jì)模式,它可以確保一個(gè)類只有一個(gè)實(shí)例,并且為整個(gè)系統(tǒng)提供一個(gè)唯一的訪問(wèn)點(diǎn)。在 JavaScript 中,我們可以使用閉包來(lái)實(shí)現(xiàn)單例模式。比如我們定義一個(gè)命名空間對(duì)象來(lái)承載模塊。
在這個(gè)例子中,我們使用一個(gè)閉包來(lái)限制代碼的作用域,并使用一個(gè)變量
接下來(lái)我們來(lái)看看另外一種常見(jiàn)的設(shè)計(jì)模式:觀察者模式。觀察者模式也叫發(fā)布-訂閱模式,它是一種對(duì)象間依賴關(guān)系的設(shè)計(jì)模式,用于解耦發(fā)布者和訂閱者之間的關(guān)系。在 JavaScript 中,我們通常使用自定義事件和消息機(jī)制來(lái)實(shí)現(xiàn)觀察者模式。
在這個(gè)例子中,我們定義了一個(gè)
最后,我們來(lái)看看一種叫做建造者模式的設(shè)計(jì)模式。建造者模式是一種創(chuàng)建型模式,它可以將復(fù)雜對(duì)象構(gòu)建過(guò)程拆分為多個(gè)簡(jiǎn)單對(duì)象的組合。在 JavaScript 中,我們可以使用類來(lái)實(shí)現(xiàn)建造者模式。
這個(gè)例子中,我們使用了 ES6 中的類來(lái)實(shí)現(xiàn)建造者模式。首先,我們定義了一個(gè)基礎(chǔ)的菜品類
首先我們先來(lái)看看最常見(jiàn)的設(shè)計(jì)模式之一:?jiǎn)卫J健卫J绞且环N特殊的設(shè)計(jì)模式,它可以確保一個(gè)類只有一個(gè)實(shí)例,并且為整個(gè)系統(tǒng)提供一個(gè)唯一的訪問(wèn)點(diǎn)。在 JavaScript 中,我們可以使用閉包來(lái)實(shí)現(xiàn)單例模式。比如我們定義一個(gè)命名空間對(duì)象來(lái)承載模塊。
var MyModule = (function() { // 實(shí)例化變量 var _instance; <br> // 模塊代碼 function init() { // ... return { // ... }; } <br> // 公有方法:返回模塊的實(shí)例,如果沒(méi)有則先創(chuàng)建 function getInstance() { if (!_instance) { _instance = init(); } return _instance; } <br> // 公有方法 return { getInstance: getInstance }; })(); <br> // 使用方式 var myModule1 = MyModule.getInstance(); var myModule2 = MyModule.getInstance(); <br> console.log(myModule1 === myModule2); // true
在這個(gè)例子中,我們使用一個(gè)閉包來(lái)限制代碼的作用域,并使用一個(gè)變量
_instance
來(lái)緩存模塊實(shí)例對(duì)象。當(dāng)我們第一次使用MyModule.getInstance()
時(shí),調(diào)用init()
函數(shù)來(lái)初始化模塊,然后把返回值賦值給_instance
。在以后的調(diào)用中,直接返回_instance
。接下來(lái)我們來(lái)看看另外一種常見(jiàn)的設(shè)計(jì)模式:觀察者模式。觀察者模式也叫發(fā)布-訂閱模式,它是一種對(duì)象間依賴關(guān)系的設(shè)計(jì)模式,用于解耦發(fā)布者和訂閱者之間的關(guān)系。在 JavaScript 中,我們通常使用自定義事件和消息機(jī)制來(lái)實(shí)現(xiàn)觀察者模式。
// 定義事件通知中心 var EventEmiter = { // 存儲(chǔ)事件的對(duì)象 events: {}, // 給事件添加監(jiān)聽(tīng)函數(shù) on: function(event, listener) { if (!this.events[event]) { this.events[event] = []; } this.events[event].push(listener); }, // 觸發(fā)指定事件 emit: function(event, data) { var listeners = this.events[event]; if (listeners) { listeners.forEach(function(listener) { listener.call(this, data); }); } } }; <br> // 訂閱事件 EventEmiter.on('sayHello', function(message) { console.log('Hello, ' + message); }); <br> // 發(fā)布事件 EventEmiter.emit('sayHello', 'world');
在這個(gè)例子中,我們定義了一個(gè)
EventEmiter
對(duì)象,它有on
和emit
兩個(gè)方法。在 JS 中,函數(shù)是一等公民,所以我們可以把函數(shù)作為參數(shù)傳遞,并使用閉包來(lái)隔離作用域。在on
方法中,我們使用一個(gè)叫事件隊(duì)列
的數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)訂閱者的監(jiān)聽(tīng)函數(shù),當(dāng)emit
方法執(zhí)行時(shí),遍歷對(duì)應(yīng)事件的監(jiān)聽(tīng)函數(shù)并執(zhí)行。最后,我們來(lái)看看一種叫做建造者模式的設(shè)計(jì)模式。建造者模式是一種創(chuàng)建型模式,它可以將復(fù)雜對(duì)象構(gòu)建過(guò)程拆分為多個(gè)簡(jiǎn)單對(duì)象的組合。在 JavaScript 中,我們可以使用類來(lái)實(shí)現(xiàn)建造者模式。
// 定義一個(gè)基礎(chǔ)的菜品類 class Dish { constructor(name, price) { this.name = name; this.price = price; } <br> getName() { return this.name; } <br> getPrice() { return this.price; } <br> //... } <br> // 定義一個(gè)套餐建造器類 class MealBuilder { constructor() { this.meal = new Meal(); } <br> addDish(dish) { this.meal.addDish(dish); return this; } <br> addMainCourse(name, price) { let mainCourse = new Dish(name, price); this.meal.addDish(mainCourse); return this; } <br> addDrink(name, price) { let drink = new Dish(name, price); this.meal.addDish(drink); return this; } <br> build() { return this.meal; } } <br> // 定義一個(gè)套餐類 class Meal { constructor() { this.dishes = []; } <br> addDish(dish) { this.dishes.push(dish); } <br> getTotalPrice() { let total = this.dishes.reduce((sum, dish) => sum + dish.getPrice(), 0); return total.toFixed(2); } <br> printMenu() { console.log('-------------Menu-------------'); console.log(this.dishes.map(dish => dish.getName() + ' ' + dish.getPrice()).join('\n')); console.log('Total Price: ' + this.getTotalPrice()); console.log('------------------------------'); } } <br> // 建造一個(gè)套餐 let meal = new MealBuilder() .addMainCourse('Hamburger', 10.98) .addDrink('Cola', 4.87) .build(); <br> // 打印菜單 meal.printMenu();
這個(gè)例子中,我們使用了 ES6 中的類來(lái)實(shí)現(xiàn)建造者模式。首先,我們定義了一個(gè)基礎(chǔ)的菜品類
Dish
,它有名字和價(jià)格兩個(gè)屬性。然后定義一個(gè)套餐類Meal
,它由多個(gè)Dish
組成。最后,我們使用套餐建造器MealBuilder
來(lái)組裝一個(gè)套餐。通過(guò)鏈?zhǔn)秸{(diào)用addDish
方法,我們可以添加任意數(shù)量的菜品,并使用build()
方法返回一個(gè)Meal
實(shí)例。