開發人員將 JavaScript 設計模式作為解決問題的模板是很合適的,但並不是說這些模式可以代替開發人員的工作。 通過設計模式,我們可以將許多開發人員的經驗結合起來,以優化過的方式來構造代碼,從而解決我們所面對的問題。設計模式還提供了用於描述問題解決方案的通用辭彙表,而不是去枯燥地描述代碼的語法和 ...
通過設計模式,我們可以將許多開發人員的經驗結合起來,以優化過的方式來構造代碼,從而解決我們所面對的問題。設計模式還提供了用於描述問題解決方案的通用辭彙表,而不是去枯燥地描述代碼的語法和語義。
JavaScript 設計模式可幫助開發人員編寫出井井有條、美觀且結構合理的代碼。儘管設計模式很容易重用,但它們並不是要取代開發人員的工作;它們是開發人員的支持與輔助,提供了與特定應用程式無關的通用解決方案,從而儘量避免那些可能導致 Web 應用程式的開發工作出現重大問題的小漏洞。
與臨時方案相比,它們消除了不必要的重覆,從而縮減了代碼庫的整體大小,並讓我們的代碼更加健壯。
在本文中,我將探討 7 種最出色和最受歡迎的 JavaScript 設計模式,這些模式主要歸為以下三類:創作設計模式、結構設計模式和行為設計模式。
1、構造函數設計模式
這是一種特殊的方法,用於在分配記憶體後初始化新創建的對象。由於 JavaScript 一般來說是面向對象的,所以它打交道最多的就是對象。於是我打算深入研究對象構造函數。在 JavaScript 中創建新對象有三種方法可用。
以下創建構造函數設計模式的一種方法。
// 創建一個新的空對象 var newObject = {}; // 創建一個新的空對象 var newObject = Object.create(Object.prototype); var newObject = newObject();
要訪問函數的屬性,你需要初始化對象。
const object = new ConstructorObject();
上面的 new 關鍵字告訴 JavaScript,一個 constructorObject 應該充當一個構造函數。這個設計模式並不支持繼承。更多細節可以參考這裡。
2、原型模式
原型模式是基於原型繼承的。在這種模式中,被創建的對象充當其他對象的原型。實際上,原型(prototype)是被創建的每個對象構造函數的藍圖。
示例:
var myCar= { name:"Ford Escort", brake:function(){ console.log("Stop! I am applying brakes"); } Panic : function (){ console.log ( "wait. how do you stop thuis thing?") } } // 使用 object create 實個新的例化一 car var yourCar= object.create(myCar); // 現在它就是另一個的原型了 console.log (yourCar.name);]
3、模塊設計模式
模塊(module)設計模式對原型模式做了一些改進。模塊模式設置了不同類型的修飾符(私有和公共)。你可以創建相似的函數或屬性而不會發生衝突。我們還可以靈活地公開重命名函數。這個設計模式的一個缺陷是無法覆蓋(override)外部環境中創建的函數。
示例:
function AnimalContainter () { const container = []; function addAnimal (name) { container.push(name); } function getAllAnimals() { return container; } function removeAnimal(name) { const index = container.indexOf(name); if(index < 1) { throw new Error('Animal not found in container'); } container.splice(index, 1) } return { add: addAnimal, get: getAllAnimals, remove: removeAnimal } } const container = AnimalContainter(); container.add('Hen'); container.add('Goat'); container.add('Sheep'); console.log(container.get()) //Array(3) ["Hen", "Goat", "Sheep"] container.remove('Sheep') console.log(container.get()); //Array(2) ["Hen", "Goat"]
4、單例模式
在僅需要創建一個實例的情況下(例如一個資料庫連接),這個模式是必需的。在這個模式中,只能在關閉連接時創建一個實例,或者在打開新實例之前必須關閉已有的實例。此模式也稱為嚴格模式,它的一個缺點是測試時的體驗很差,因為它隱藏的依賴項對象很難挑出來進行測試。
示例:
function DatabaseConnection () { let databaseInstance = null; // 追蹤特定時間創建實例的數量 let count = 0; function init() { console.log(`Opening database #${count + 1}`); // 現在執行操作 } function createIntance() { if(databaseInstance == null) { databaseInstance = init(); } return databaseInstance; } function closeIntance() { console.log('closing database'); databaseInstance = null; } return { open: createIntance, close: closeIntance } } const database = DatabseConnection(); database.open(); //Open database #1 database.open(); //Open database #1 database.open(); //Open database #1 database.close(); //close database
5、工廠模式
這個模式的創新之處在於,它不需要構造函數就能創建對象。它提供了用於創建對象的通用介面,我們可以在其中指定要創建的工廠(factory)對象的類型。這樣一來,我們只需指定對象,然後工廠會實例化並返回這個對象供我們使用。當對象組件設置起來很複雜,並且我們希望根據所處的環境輕鬆地創建不同的對象實例時,使用工廠模式就是很明智的選擇。在處理許多共用相同屬性的小型對象,以及創建一些需要解耦的對象時也可以使用工廠模式。
示例:
// Dealer A DealerA = {}; DealerA.title = function title() { return "Dealer A"; }; DealerA.pay = function pay(amount) { console.log( `set up configuration using username: ${this.username} and password: ${ this.password }` ); return `Payment for service ${amount} is successful using ${this.title()}`; }; //Dealer B DealerB = {}; DealerB.title = function title() { return "Dealer B"; }; DealerB.pay = function pay(amount) { console.log( `set up configuration using username: ${this.username} and password: ${this.password}` ); return `Payment for service ${amount} is successful using ${this.title()}`; }; //@param {*} DealerOption //@param {*} config function DealerFactory(DealerOption, config = {}) { const dealer = Object.create(dealerOption); Object.assign(dealer, config); return dealer; } const dealerFactory = DealerFactory(DealerA, { username: "user", password: "pass" }); console.log(dealerFactory.title()); console.log(dealerFactory.pay(12)); const dealerFactory2 = DealerFactory(DealerB, { username: "user2", password: "pass2" }); console.log(dealerFactory2.title()); console.log(dealerFactory2.pay(50));
6、觀察者模式
觀察者(observer)設計模式在許多對象同時與其他對象集通信的場景中用起來很方便。在觀察者模式中不會在狀態之間發生不必要的事件 push 和 pull;相比之下,所涉及的模塊僅會修改數據的當前狀態。
示例:
function Observer() { this.observerContainer = []; } Observer.prototype.subscribe = function (element) { this.observerContainer.push(element); } // 下麵是從 container 中移除一個元素 Observer.prototype.unsubscribe = function (element) { const elementIndex = this.observerContainer.indexOf(element); if (elementIndex > -1) { this.observerContainer.splice(elementIndex, 1); } } /** * we notify elements added to the container by calling * each subscribed components added to our container */ Observer.prototype.notifyAll = function (element) { this.observerContainer.forEach(function (observerElement) { observerElement(element); }); }
7、命令模式 最後介紹的是命令(command)模式。命令設計模式將方法調用、操作或請求封裝到單個對象中,以便我們可以自行傳遞方法調用。命令設計模式讓我們可以從任何正在執行的命令中發出命令,並將責任委托給與之前不同的對象。這些命令以 run() 和 execute() 格式顯示。
(function(){ var carManager = { // 請求的信息 requestInfo: function( model, id ){ return "The information for " + model + " with ID " + id + " is foo bar"; }, // 現在購買這個 car buyVehicle: function( model, id ){ return "You have successfully purchased Item " + id + ", a " + model; }, // 現在 arrange viewing arrangeViewing: function( model, id ){ return "You have successfully booked a viewing of " + model + " ( " + id + " ) "; } }; })();
小結
如果你覺得這篇文章不錯,請別忘記點個贊
跟關註
哦~