1. 程式人生 > >23種JavaScript設計模式

23種JavaScript設計模式

幫助 情況下 包裝 叠代器 生命周期 重新 哪些 屏幕 .com

原文鏈接:https://boostlog.io/@sonuton/23-javascript-design-patterns-5adb006847018500491f3f7f

轉自:

https://mp.weixin.qq.com/s?__biz=MzUxMzcxMzE5Ng==&mid=2247488996&idx=1&sn=c337e4cfe2a67550f5f22536d58a9735&chksm=f951a0a7ce2629b13bb306f9a2410e2be8e9f6958756be40c36937371c4ff5dfef2b78bbbb19&mpshare=1&scene=23&srcid=060272XasmJGVAm6EohoEzw7#rd

作者|sonuton

譯者|胡紅星

編輯|覃雲

1.為什麽要學習設計模式?

在許多訪談中,你可能會遇到很多面向對象編程中的接口,抽象類,代理和以及其他與設計模式相關的問題。 一旦了解了設計模式,它會讓你輕松應對任何訪談,並可以在你的項目中應用這些特性。在應用程序中實現設計模式已經得到驗證和測試。

為了使應用程序具有可擴展性,可靠性和易維護性,應該編寫符合設計模式的代碼。

2.什麽是設計模式。

  • 設計模式是我們每天編程遇到的問題的可重用解決方案。

  • 設計模式主要是為了解決對象的生成和整合問題。

  • 換句話說,設計模式可以作為可應用於現實世界編程問題的模板。

3.設計模式的發展歷史

設計模式的概念是由四人幫(《設計模式(可復用面向對象軟件的基礎)》的四位作者)提出。

四人幫把這本書分成兩部分:

  • 第一部分解釋面向對象編程的優缺點。

  • 第二部分是關於 23 個經典設計模式的演變。

自提出設計模式概念後,四人幫設計模式在軟件開發生命周期中發揮了重要作用。

4.設計模式分類

根據實際應用中遇到的不同問題,四人幫將設計模式分為三種類型。

  • 創建型模式

  • 結構型模式

  • 行為型模式

接下來將概述屬於這三種類型的 23 種設計模式的主要概念。

4.1創建型模式

這類模式用於對象的生成和生命周期的管理。

創造模式可以決定生成哪些對象,提高了程序的靈活性。模式如下:

  • 抽象工廠模式

  • 生成器模式

  • 工廠方法模式

  • 單例模式

  • 原型模式

4.1.1JavaScript 抽象工廠模式

# 抽象工廠模式究竟是什麽?

它就像一個工廠,但一切都被封裝起來:

  • 提供對象的方法

  • 構建對象的工廠

  • 最終的對象

  • 最終對象包含使用策略模式的對象

策略模式只是使用組合的方式,換句話說,它的類字段實際上是對象本身。

# 抽象工廠的用處?

抽象工廠模式可以創建類簇類的對象,而不需要指定具體的類,這使得抽象工廠很靈活。

通過抽象工廠模式可以對任何類簇對象進行建模並通過統一的接口供外部對象使用。

抽象工廠唯一不好的地方是它可能變得非常復雜。

4.1.2JavaScript 的生成器模式(Builder 模式)

#Builder 模式是什麽?

Builder 模式是一種用於創建由其他對象組合構成的對象的模式。創建部件的方法應該獨立於主對象。另外,為了從業務方隱藏部件的創建細節,兩者是相互獨立的。

在使用生成器模式時,生成器知道所有的細節,且創建細節完全對其他相關類屏蔽。

4.1.3JavaScript 工廠方法模式

# 什麽是工廠方法模式?

根據定義,只要想一個方法返回公共超類的幾個可能的類中的一個,就可以使用工廠模式。

假設我想隨機向屏幕上射擊敵人。那麽如果所有東西都硬編碼好了,並且不知道敵人的具體類型會讓處理變得很困難。

但是,假設我創建了一個隨機數生成器,每個可能的敵人類都由一個數字代替,並可以由該隨機數生成器返回。

然後可以將這個數字發送給工廠對象,這樣可以返回一個動態創建的敵人。

所以,MOL 的主要概念非常重要,我們希望能夠在運行時選擇類,這就是工廠模式能夠提供的。

#何時使用工廠方法模式?

當不知道需要何種類型的對象時可以使用工廠方法模式。

但是,有一點需要註意,確保所有潛在的類都具有相同的子類層次結構,這意味著在繼承路徑上有相同的父類。

可以使用工廠模式來集中類別選擇的代碼。或是不希望用戶知道每一個可能的子類時。

4.1.4JavaScript 單例模式

# 什麽是單例模式?

當想要避免實例化多個對象時使用單例模式。單例使得只能從類實例化一個對象。

現在你可能會問自己,我什麽時候會想要這樣做? 其實,有很多場景。

我們已經演示過拼字遊戲裏使用一個類容納所有可能的字母,並且拼字遊戲是一款非常常見的棋盤遊戲,這裏使用單例模式是很明智的選擇。

這個單例類包含所有可能的拼字遊戲字母,以便玩家可以使用這個單例類取得所有字母,不同玩家可以同時請求獲取。

單例使得每個玩家都共享相同的字母列表,每個玩家可以根據這個字母列表來拼接自己的單詞。

4.1.5JavaScript 原型模式

#什麽是原型模式?

當想要通過克隆或拷貝對象來生成對象時,這就是原型模式。

通過原型模式可以在運行時添加已知父類的子類實例。

當有許多類只在運行時需要使用時可以使用原型模式。原型模式的好處之一是減少了創建多個子類。

4.2結構型模式

這類模式描述了向現有對象添加功能的不同方式簡單地說,這個模式著重於解耦對象的接口實現模式如下:

  • 適配器模式

  • 橋接模式

  • 組合模式

  • 裝飾者模式

  • 外觀模式

  • 享元模式

  • 代理模式

4.2.1JavaScript 適配器設計模式

#適配器模式的作用

適配器設計模式允許使用兩個完全不兼容的接口一起工作,正如其名字一樣,適配不同接口。

假設你墻上的插座只有兩座插頭,但是你想連接一個三座的插頭,這時就需要適配器了。

當客戶期望使用目標接口是兩座插頭,但是你只有三座插頭,這就是適配器將要執行的操作 把三座轉換成兩座。

適配器模式允許使用任何現有接口適配為目標接口。

從另一個角度看任何類都可以協同工作只要適配器解決了所有類都必須實現相同接口的問題。

4.2.2JavaScript 橋接模式

#什麽是橋接模式?

官方定義是將抽象與其實現分離開來,因此兩者可以獨立變化。

該模式用於將抽象與其實現分開,以便兩者都可以獨立修改。該模式包含一個用於橋接抽象類和實現類的接口。通過橋接模式,兩種類型都可以修改而不會相互影響。

#橋接模式實現指南

當想要避免抽象與其實現之間的永久綁定時可以使用橋接模式。

抽象和它們的實現都應該可以通過子類進行擴展。當抽象的實現有變化時不應該影響到調用方,及調用方不需要重新編譯。

當需要在多個對象之間共享一個實現時,可以選擇這種模式。

最後我們希望完全對調用方隱藏抽象的實現。

4.2.3JavaScript 組合模式

組合模式從定義上看起來很復雜,一旦用起來就會感覺很合理。

它允許統一處理單個對象和對象組合,這是組合設計模式的典型定義。

組合模式可以表示為部分 - 整體的層次結構。該結構的組件又可以劃分為更小的組件。

一個更合乎邏輯的定義是組合設計模式是用來結構化數據或單獨表示整個對象的每個部分的互相操作。

4.2.4JavaScript 裝飾模式

#什麽是裝飾模式?

動態的為一個對象附加額外的功能,裝飾模式可以不通過繼承來實現功能擴展。

這種模式屬於結構設計模式類別,也被稱為包裝模式,裝飾設計模式解決了在不改變對象現有結構的情況下添加附加功能的問題。

另外,該模式創建了一個裝飾器類,它包裝原始類並在運行時向對象添加新的行為或操作。

# 裝飾模式的實現指南

當選擇這種模式時,需要動態地向單個對象添加新的功能,並且而不會影響其他對象。

例如,在有些情況下,為原有代碼添加新的功能可能會很困難,用修飾器修改代碼會更容易些。

通過繼承來實現功能擴展會產生大量的子類,並且有可能這些子類還不足以覆蓋所有需要擴展的功能。

當無法查看類定義或無法繼承時,需要選擇裝飾模式。

例如,盡管類被封裝起來無法修改,通過裝飾模式仍然可以進行擴展,並且,我相信你肯定也遇到過無法通過繼承來實現功能擴展的情況,在這些情況下,選擇裝飾模式。

4.2.5JavaScript 外觀模式

#什麽是外觀模式?

為子系統中的一組接口提供統一接口。外觀模式定義了一個更高層次的接口,使子系統更易於使用。術語外觀來自法語 fa?ade,意思是正面或臉。

簡單來說是外觀模式隱藏了子系統的實現復雜性,為我們提供了一個簡潔的接口。該接口負責調用現有子系統的功能。

#外觀模式實現指南

當我們想為子系統提供一個簡單的接口時需要使用外觀模式。隨著子系統的發展,子系統往往會變得更加復雜。

當我們在應用一些模式時,大多數模式會導致更多的類創建出來,這使得子系統可用性更好,更容易自定義需要的功能,但對於不太需要自定義的業務方而言,它也變得更加困難。

外觀模式將子系統包裝成一個簡單默認的接口,足以應付大多數情況的使用。

另外,當業務方和子系統的實現存在過多依賴時也可以選擇外觀模式。

在這種情況下,外觀模式將子系統從業務方和其他子系統中分離出來,從而提高子系統的獨立性和可移植性。

到目前為止,如果子系統過於耦合,那麽可以通過外觀模式提供的接口來簡化子系統之間的依賴。

4.2.6JavaScript 享元模式

#什麽是享元模式?

當需要創建大量相似對象時需要使用享元模式,這裏的大量是上萬的量級而不是平時接觸的上百。

享元模式通過共享對象的相似部分,避免重復創建,來達到減小內存的使用。

4.2.7JavaScript 代理模式

# 什麽是代理設計模式?

代理是一個將被用來限制訪問另一個類的類。

這可能是出於安全的考慮,通過代理來決定需要代理的對象哪些方法是可用的。

4.3行為型模式

這類模式描述了對象如何相互作用,模式如下:

  • 責任鏈模式

  • 命令模式

  • 解釋器模式

  • 叠代器模式

  • 中介者模式

  • 備忘錄模式

  • 觀察者模式

  • 狀態模式

  • 策略模式

  • 模板方法模式

  • 訪問者模式

4.3.1JavaScript 責任鏈模式

#什麽是責任鏈模式?

責任鏈模式有一組對象,期望它們之間能夠解決問題,如果第一個對象無法解決它,則將數據傳遞給責任鏈中的下一個數據。

通過多個接收者對象來處理請求,避免將請求的發送者耦合到其接收者。將接收對象串聯起來,傳遞請求直到被其中一個處理掉。

責任鏈模式為請求創建一系列接收者對象。 在這種模式下,通常每個接收器都包含對另一個接收器的引用。

如果一個接收者不能處理該請求,則它將請求傳遞給下一個接受者。

4.3.2JavaScript 命令模式

#什麽是命令模式?

命令設計模式是一種行為設計模式,其對象用於表示和封裝稍後調用某個方法所需的所有信息。該信息包括方法名稱,擁有方法的對象和方法參數的值。

基本上,它允許你做的是存儲代碼清單,在稍後或多次執行,並且通常使用命令模式可以撤銷命令。

當這些封裝的對象調用 execute() 方法,業務方或程序會執行指定命令或一段代碼。

然後,調用者對象在調用時會傳遞命令給命令接收者,命令接收者擁有實際想要執行的代碼,一旦從調用者接收到命令就立馬執行。

例如有個"TurnTVOn”的命令對象,然後一個“DeviceButton”的對象,一旦"DeviceButton"對象被調用就會發送"TurnTVOn"命令。所有這些之間的接口可以使用多態,所以無論何時調用 TurnTVOn,該方法將由命令接收者執行。

4.3.3JavaScript 解釋器模式

# 什麽是解釋器模式?

解釋器模式很容易被忽略,並且網上很少有使用這種模式。

但是,如果與 JavaScript 反射技術結合使用,會變得非常有用。它用於將數據的一種表示轉換為另一種表示。

4.3.4JavaScript 叠代器模式

# 什麽是叠代器模式?

叠代器模式提供一種統一的方式來訪問不同類型的對象集合。

例如,Array,ArrayList 和 HashTable,這三個集合包含相同類型的對象,通過叠代器可以取到集合裏的每一個元素,並做相同的處理。

叠代器模式做的是提供統一的方式來循環遍歷這些不同類型的集合。

4.3.5JavaScript 中介者計模式

#什麽是中介者模式?

用於處理相關對象之間的通信。所有通信由中介者完成,通信雙方不需要了解對方的任何信息。

更嚴格的定義是,中介者模式允許通過封裝不同對象之間相互作用和相互通信的方式來實現松耦合,並且中介者模式允許每個對象的行為彼此獨立地變化。

4.3.6JavaScript 的備忘錄模式

#什麽是備忘錄模式?

用於存儲對象以前狀態的模式,首先,備忘錄模式需要一個備忘錄對象用於存儲對象的不同狀態,不同的狀態及一些字段擁有不同的值。

然後,用於從當前目標備忘錄對象讀寫值的初始對象,創建新的備忘錄對象並賦值給當前備忘錄對象。

最後,內部是一個 ArrayList 對象用於持有之前所有的備忘錄對象,該 ArrayList 對象同時用於存儲和檢索備忘錄對象。

4.3.7JavaScript 觀察者模式

# 什麽時候使用觀察者模式?

當另一個對象更改時需要其他對象接收更新。例如,假設我們有一個對象或發布者代表股票市場中的數千個股票,當需要將更新發送給多個訂閱者時,可以使用觀察者模式來完成。

#觀察者模式的好處

松耦合。 對象或發布者完全不用知道觀察者或訂閱者的存在,我把這分為兩種不同的概念,因為我覺得發布 - 訂閱更有意義,但 OLP 的基本術語使用的是對象 - 觀察者。

#壞處

觀察者模式唯一的缺點是對象或發布者可能發送對觀察者,訂閱者無關緊要的更新。

4.3.8JavaScript 狀態模式

#什麽是狀態模式?

它允許對象在其內部狀態改變時改變其行為,這樣讓對象看起來改變了它所屬的類。

狀態模式主要分為三個部分:

首先,將擁有所謂的“上下文”或“賬戶”,它將要做的是維護一個將定義當前狀態的 ConcreteState 子類的實例。

然後,擁有“狀態”,該狀態定義了一個用於封裝與上下文特定狀態關聯的行為接口。

最後是具體的狀態,每個子類將實現與上下文狀態相關的行為。

4.3.9JavaScript 策略模式

# 何時使用策略模式?

如果要定義一個類,該類將具有與列表中的所有其他行為相似的行為,可以使用策略模式。

例如,有的動物可以飛,有的動物不能飛,這裏的相似行為就是飛行,不論該動物是否能飛行。

可以從以下類中選擇類對象:

  • 不會飛行

  • 用翅膀飛翔

  • 飛得快

通過策略模式可以動態的創建全新的不同類型的飛行類動物。

當需要動態決定需要使用的行為時可以使用策略模式。

# 使用策略模式的其他好處

它通常會減少很長的條件列表,所以如果你看到使用許多不同類型的條件時,策略模式會很有幫助。當然,還避免了重復的代碼。

策略模式可以防止其他類的變化影響到當前類。也可以向業務方隱藏復雜和敏感代碼。

壞處:策略模式會增加對象和類的數量。

4.3.10JavaScript 模板方法模式

#什麽是模板方法模式?

用於創建一組執行類似方法的子類。

要實現它,需要創建一個抽象類,它將包含一個名為模板方法的方法。

創建包含稱為模板方法的抽象類,並且模板方法包含每個子類對象將調用的一系列方法調用。在某些情況下子類也會重載一些不合適的方法調用。

4.3.11JavaScript 訪問者模式

# 什麽是訪問者模式?

訪問者模式允許將方法添加到不同類型的類中 - 但它們不必是不同的類型 - 只會讓復雜度有所增加,並不會對類有太多修改。

這可以根據所使用的類制作完全不同的方法。

也可以說訪問者模式可以為現有類創建外部類來進行擴展以避免對原有類做修改。

註意:掌握抽象,繼承,多態,封裝,接口,類和抽象類等面向對象概念的基本知識對於更好地理解設計模式非常重要。

23種JavaScript設計模式