GOF提出的23種設計模式是哪些 設計模式有建立形、行爲形、結構形三種類別 經常使用的Javascript中經常使用設計模式的其中17種 詳解設計模式六大原則

20151218markhtml

 

延伸擴展:正則表達式

-設計模式在不少語言PHP、JAVA、C#、C++、JS等都有各自的使用,但原理是相同的,好比JS經常使用的Javascript設計模式算法

-詳解設計模式六大原則設計模式

設計模式(面向對象)有六大原則:數據結構

開閉原則(Open Closed Principle,OCP)
里氏代換原則(Liskov Substitution Principle,LSP)
依賴倒轉原則(Dependency Inversion Principle,DIP)
接口隔離原則(Interface Segregation Principle,ISP)
合成/聚合複用原則(Composite/Aggregate Reuse Principle,CARP)
最小知識原則(Principle of Least Knowledge,PLK,也叫迪米特法則)函數

 

原文:23種設計模式工具

目錄post

建立型測試

1. Factory Method(工廠方法)ui

2. Abstract Factory(抽象工廠)

3. Builder(建造者)

4. Prototype(原型)

5. Singleton(單例)

結構型

6. Adapter Class/Object(適配器)

7. Bridge(橋接)

8. Composite(組合)

9. Decorator(裝飾)

10. Facade(外觀)

11. Flyweight(享元)

12. Proxy(代理)

行爲型

13. Interpreter(解釋器)

14. Template Method(模板方法)

15. Chain of Responsibility(責任鏈)

16. Command(命令)

17. Iterator(迭代器)

18. Mediator(中介者)

19. Memento(備忘錄)

20. Observer(觀察者)

21. State(狀態)

22. Strategy(策略)

23. Visitor(訪問者)

建立型
1. Factory Method(工廠方法)
clip_image001

意圖:

定義一個用於建立對象的接口,讓子類決定實例化哪個類。Factory Method 使一個類的實例化延遲到其子類。

適用性:

當一個類不知道它所必須建立的對象的類的時候。

當一個類但願由它的子類來指定它所建立的對象的時候。

當類將建立對象的職責委託給多個幫助子類中的某一個,而且你但願將哪個幫助子類是代理者這一信息局部化的時候。

2. Abstract Factory(抽象工廠)
clip_image002

意圖:

提供一個建立一系列相關或相互依賴對象的接口,而無需指定它們具體的類。
適用性:

一個系統要獨立於它的產品的建立、組合和表示時。

一個系統要由多個產品系列中的一個來配置時。

當你要強調一系列相關的產品對象的設計以便進行聯合使用時。

當你提供一個產品類庫,而只想顯示它們的接口而不是實現時。

3. Builder(建造者)
clip_image003

意圖:

將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。

適用性:

當建立複雜對象的算法應該獨立於該對象的組成部分以及它們的裝配方式時。

當構造過程必須容許被構造的對象有不一樣的表示時。

4. Prototype(原型)
clip_image004

意圖:

用原型實例指定建立對象的種類,而且經過拷貝這些原型建立新的對象。

適用性:

當要實例化的類是在運行時刻指定時,例如,經過動態裝載;或者

爲了不建立一個與產品類層次平行的工廠類層次時;或者

當一個類的實例只能有幾個不一樣狀態組合中的一種時。創建相應數目的原型並克隆它們可能比每次用合適的狀態手工實例化該類更方便一些。

5. Singleton(單例)
clip_image005

意圖:

保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。

適用性:

當類只能有一個實例並且客戶能夠從一個衆所周知的訪問點訪問它時。

當這個惟一實例應該是經過子類化可擴展的,而且客戶應該無需更改代碼就能使用一個擴展的實例時。

結構型
6. Adapter Class/Object(適配器)
clip_image006
意圖:

將一個類的接口轉換成客戶但願的另一個接口。Adapter 模式使得本來因爲接口不兼容而不能一塊兒工做的那些類能夠一塊兒工做。
適用性:

你想使用一個已經存在的類,而它的接口不符合你的需求。

你想建立一個能夠複用的類,該類能夠與其餘不相關的類或不可預見的類(即那些接口可能不必定兼容的類)協同工做。

(僅適用於對象Adapter )你想使用一些已經存在的子類,可是不可能對每個都進行子類化以匹配它們的接口。對象適配器能夠適配它的父類接口。

7. Bridge(橋接)
clip_image007

意圖:

將抽象部分與它的實現部分分離,使它們均可以獨立地變化。

適用性:

你不但願在抽象和它的實現部分之間有一個固定的綁定關係。例如這種狀況多是由於,在程序運行時刻實現部分應能夠被選擇或者切換。

類的抽象以及它的實現都應該能夠經過生成子類的方法加以擴充。這時Bridge 模式使你能夠對不一樣的抽象接口和實現部分進行組合,並分別對它們進行擴充。

對一個抽象的實現部分的修改應對客戶不產生影響,即客戶的代碼沒必要從新編譯。

(C++)你想對客戶徹底隱藏抽象的實現部分。在C++中,類的表示在類接口中是可見的。

有許多類要生成。這樣一種類層次結構說明你必須將一個對象分解成兩個部分。Rumbaugh 稱這種類層次結構爲「嵌套的普化」(nested generalizations )。

你想在多個對象間共享實現(可能使用引用計數),但同時要求客戶並不知道這一點。一個簡單的例子即是Coplien 的String 類[ Cop92 ],在這個類中多個對象能夠共享同一個字符串表示(StringRep )。

8. Composite(組合)
clip_image008
意圖:

將對象組合成樹形結構以表示「部分-總體」的層次結構。C o m p o s i t e 使得用戶對單個對象和組合對象的使用具備一致性。
適用性:

你想表示對象的部分-總體層次結構。

你但願用戶忽略組合對象與單個對象的不一樣,用戶將統一地使用組合結構中的全部對象。

9. Decorator(裝飾)
clip_image009
意圖:
動態地給一個對象添加一些額外的職責。就增長功能來講,Decorator 模式相比生成子類更爲靈活。
適用性:

在不影響其餘對象的狀況下,以動態、透明的方式給單個對象添加職責。

處理那些能夠撤消的職責。

當不能採用生成子類的方法進行擴充時。一種狀況是,可能有大量獨立的擴展,爲支持每一種組合將產生大量的子類,使得子類數目呈爆炸性增加。另外一種狀況多是由於類定義被隱藏,或類定義不能用於生成子類。

10. Facade(外觀)
clip_image010

意圖:

爲子系統中的一組接口提供一個一致的界面,Facade模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。

適用性:

當你要爲一個複雜子系統提供一個簡單接口時。子系統每每由於不斷演化而變得愈來愈複雜。大多數模式使用時都會產生更多更小的類。這使得子系統更具可重用性,也更容易對子系統進行定製,但這也給那些不須要定製子系統的用戶帶來一些使用上的困難。Facade 能夠提供一個簡單的缺省視圖,這一視圖對大多數用戶來講已經足夠,而那些須要更多的可定製性的用戶能夠越過facade層。

客戶程序與抽象類的實現部分之間存在着很大的依賴性。引入facade 將這個子系統與客戶以及其餘的子系統分離,能夠提升子系統的獨立性和可移植性。

當你須要構建一個層次結構的子系統時,使用facade模式定義子系統中每層的入口點。若是子系統之間是相互依賴的,你可讓它們僅經過facade進行通信,從而簡化了它們之間的依賴關係。

11. Flyweight(享元)
clip_image011

意圖:

運用共享技術有效地支持大量細粒度的對象。

適用性:

一個應用程序使用了大量的對象。

徹底因爲使用大量的對象,形成很大的存儲開銷。

對象的大多數狀態均可變爲外部狀態。

若是刪除對象的外部狀態,那麼能夠用相對較少的共享對象取代不少組對象。

應用程序不依賴於對象標識。因爲Flyweight 對象能夠被共享,對於概念上明顯有別的對象,標識測試將返回真值。

12. Proxy(代理)
clip_image012

意圖:

爲其餘對象提供一種代理以控制對這個對象的訪問。

適用性:

在須要用比較通用和複雜的對象指針代替簡單的指針的時候,使用Proxy模式。下面是一 些可使用Proxy 模式常見狀況:
1) 遠程代理(Remote Proxy )爲一個對象在不一樣的地址空間提供局部表明。 NEXTSTEP[Add94] 使用NXProxy 類實現了這一目的。Coplien[Cop92] 稱這種代理爲「大使」 (Ambassador )。
2 )虛代理(Virtual Proxy )根據須要建立開銷很大的對象。在動機一節描述的ImageProxy 就是這樣一種代理的例子。
3) 保護代理(Protection Proxy )控制對原始對象的訪問。保護代理用於對象應該有不一樣 的訪問權限的時候。例如,在Choices 操做系統[ CIRM93]中KemelProxies爲操做系統對象提供 了訪問保護。
4 )智能指引(Smart Reference )取代了簡單的指針,它在訪問對象時執行一些附加操做。 它的典型用途包括:

對指向實際對象的引用計數,這樣當該對象沒有引用時,能夠自動釋放它(也稱爲SmartPointers[Ede92 ] )。

當第一次引用一個持久對象時,將它裝入內存。

在訪問一個實際對象前,檢查是否已經鎖定了它,以確保其餘對象不能改變它。

行爲型
13. Interpreter(解釋器)
clip_image013

意圖:

給定一個語言,定義它的文法的一種表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。

適用性:

當有一個語言須要解釋執行, 而且你可將該語言中的句子表示爲一個抽象語法樹時,可以使用解釋器模式。而當存在如下狀況時該模式效果最好:

該文法簡單對於複雜的文法, 文法的類層次變得龐大而沒法管理。此時語法分析程序生成器這樣的工具是更好的選擇。它們無需構建抽象語法樹便可解釋表達式, 這樣能夠節省空間並且還可能節省時間。

效率不是一個關鍵問題最高效的解釋器一般不是經過直接解釋語法分析樹實現的, 而是首先將它們轉換成另外一種形式。例如,正則表達式一般被轉換成狀態機。但即便在這種狀況下, 轉換器仍可用解釋器模式實現, 該模式還是有用的。

14. Template Method(模板方法)
clip_image014

意圖:

定義一個操做中的算法的骨架,而將一些步驟延遲到子類中。TemplateMethod 使得子類能夠不改變一個算法的結構便可重定義該算法的某些特定步驟。

適用性:

一次性實現一個算法的不變的部分,並將可變的行爲留給子類來實現。

各子類中公共的行爲應被提取出來並集中到一個公共父類中以免代碼重複。這是Opdyke 和Johnson 所描述過的「重分解以通常化」的一個很好的例子[ OJ93 ]。首先識別現有代碼中的不一樣之處,而且將不一樣之處分離爲新的操做。最後,用一個調用這些新的操做的模板方法來替換這些不一樣的代碼。

控制子類擴展。模板方法只在特定點調用「hook 」操做(參見效果一節),這樣就只容許在這些點進行擴展。

15. Chain of Responsibility(責任鏈)
clip_image015

意圖:

使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關係。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理它爲止。

適用性:

有多個的對象能夠處理一個請求,哪一個對象處理該請求運行時刻自動肯定。

你想在不明確指定接收者的狀況下,向多個對象中的一個提交一個請求。

可處理一個請求的對象集合應被動態指定。

16. Command(命令)
clip_image016

意圖:

將一個請求封裝爲一個對象,從而使你可用不一樣的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可撤消的操做。

適用性:

抽象出待執行的動做以參數化某對象,你可用過程語言中的回調(call back)函數表達這種參數化機制。所謂回調函數是指函數先在某處註冊,而它將在稍後某個須要的時候被調用。Command 模式是回調機制的一個面向對象的替代品。

在不一樣的時刻指定、排列和執行請求。一個Command對象能夠有一個與初始請求無關的生存期。若是一個請求的接收者可用一種與地址空間無關的方式表達,那麼就可將負責該請求的命令對象傳送給另外一個不一樣的進程並在那兒實現該請求。

支持取消操做。Command的Excute 操做可在實施操做前將狀態存儲起來,在取消操做時這個狀態用來消除該操做的影響。Command 接口必須添加一個Unexecute操做,該操做取消上一次Execute調用的效果。執行的命令被存儲在一個歷史列表中。可經過向後和向前遍歷這一列表並分別調用Unexecute和Execute來實現重數不限的「取消」和「重作」。

支持修改日誌,這樣當系統崩潰時,這些修改能夠被重作一遍。在Command接口中添加裝載操做和存儲操做,能夠用來保持變更的一個一致的修改日誌。從崩潰中恢復的過程包括從磁盤中從新讀入記錄下來的命令並用Execute操做從新執行它們。

用構建在原語操做上的高層操做構造一個系統。這樣一種結構在支持事務( transaction)的信息系統中很常見。一個事務封裝了對數據的一組變更。Command模式提供了對事務進行建模的方法。Command有一個公共的接口,使得你能夠用同一種方式調用全部的事務。同時使用該模式也易於添加新事務以擴展系統。

17. Iterator(迭代器)
clip_image017

意圖:

提供一種方法順序訪問一個聚合對象中各個元素, 而又不需暴露該對象的內部表示。

適用性:

訪問一個聚合對象的內容而無需暴露它的內部表示。

支持對聚合對象的多種遍歷。

爲遍歷不一樣的聚合結構提供一個統一的接口(即, 支持多態迭代)。

18. Mediator(中介者)
clip_image018

意圖:

用一箇中介對象來封裝一系列的對象交互。中介者使各對象不須要顯式地相互引用,從而使其耦合鬆散,並且能夠獨立地改變它們之間的交互。

適用性:

一組對象以定義良好可是複雜的方式進行通訊。產生的相互依賴關係結構混亂且難以理解。

一個對象引用其餘不少對象而且直接與這些對象通訊,致使難以複用該對象。

想定製一個分佈在多個類中的行爲,而又不想生成太多的子類。

19. Memento(備忘錄)
clip_image019

意圖:

在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象以外保存這個狀態。這樣之後就可將該對象恢復到原先保存的狀態。

適用性:

必須保存一個對象在某一個時刻的(部分)狀態, 這樣之後須要時它才能恢復到先前的狀態。

若是一個用接口來讓其它對象直接獲得這些狀態,將會暴露對象的實現細節並破壞對象的封裝性。

20. Observer(觀察者)
clip_image020

意圖:

定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時, 全部依賴於它的對象都獲得通知並被自動更新。

適用性:

當一個抽象模型有兩個方面, 其中一個方面依賴於另外一方面。將這兩者封裝在獨立的對象中以使它們能夠各自獨立地改變和複用。

當對一個對象的改變須要同時改變其它對象, 而不知道具體有多少對象有待改變。

當一個對象必須通知其它對象,而它又不能假定其它對象是誰。換言之, 你不但願這些對象是緊密耦合的。

21. State(狀態)
clip_image021

意圖:

容許一個對象在其內部狀態改變時改變它的行爲。對象看起來彷佛修改了它的類。

適用性:

一個對象的行爲取決於它的狀態, 而且它必須在運行時刻根據狀態改變它的行爲。

一個操做中含有龐大的多分支的條件語句,且這些分支依賴於該對象的狀態。這個狀態一般用一個或多個枚舉常量表示。一般, 有多個操做包含這一相同的條件結構。State模式將每個條件分支放入一個獨立的類中。這使得你能夠根據對象自身的狀況將對象的狀態做爲一個對象,這一對象能夠不依賴於其餘對象而獨立變化。

22. Strategy(策略)
clip_image022

意圖:

定義一系列的算法,把它們一個個封裝起來, 而且使它們可相互替換。本模式使得算法可獨立於使用它的客戶而變化。

適用性:

許多相關的類僅僅是行爲有異。「策略」提供了一種用多個行爲中的一個行爲來配置一個類的方法。

須要使用一個算法的不一樣變體。例如,你可能會定義一些反映不一樣的空間/時間權衡的算法。當這些變體實現爲一個算法的類層次時[H087] ,可使用策略模式。

算法使用客戶不該該知道的數據。可以使用策略模式以免暴露覆雜的、與算法相關的數據結構。

一個類定義了多種行爲, 而且這些行爲在這個類的操做中以多個條件語句的形式出現。將相關的條件分支移入它們各自的Strategy類中以代替這些條件語句。

23. Visitor(訪問者)
clip_image023

意圖:

定義一個操做中的算法的骨架,而將一些步驟延遲到子類中。TemplateMethod 使得子類能夠不改變一個算法的結構便可重定義該算法的某些特定步驟。

適用性:

一次性實現一個算法的不變的部分,並將可變的行爲留給子類來實現。

各子類中公共的行爲應被提取出來並集中到一個公共父類中以免代碼重複。這是Opdyke和Johnson所描述過的「重分解以通常化」的一個很好的例子[OJ93]。首先識別現有代碼中的不一樣之處,而且將不一樣之處分離爲新的操做。最後,用一個調用這些新的操做的模板方法來替換這些不一樣的代碼。

控制子類擴展。模板方法只在特定點調用「hook 」操做(參見效果一節),這樣就只容許在這些點進行擴展。

相關文章
相關標籤/搜索