1. 程式人生 > 實用技巧 >開發人員都應該瞭解的 7 種 JavaScript 設計模式

開發人員都應該瞭解的 7 種 JavaScript 設計模式

開發人員將 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 &gt; -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 + " ) ";
 }
 };
 })();

小結

對於 JavaScript 開發人員來說,使用設計模式的好處很多。設計模式的一些主要優點包括提升專案的可維護性,還能減少開發週期中不必要的工作。JavaScript 設計模式可以為複雜的問題提供解決方案,提升開發速度並提高生產率。但並不能說這些設計模式就可以讓開發人員偷懶了。

如果你覺得這篇文章不錯,請別忘記點個關注哦~