23種設計模式一覽

一.創建型模式 
1.單件模式 
意圖 
保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。 


適用性 
        當類只能有一個實例而且客戶可以從一個衆所周知的訪問點訪問它時。 
        當這個唯一實例應該是通過子類化可擴展的,並且客戶應該無需更改代碼就能使用一個 
        擴展的實例時。 


2.抽象工廠 


意圖 
提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。 


適用性 
        一個系統要獨立於它的產品的創建、組合和表示時。 
        一個系統要由多個產品系列中的一個來配置時。 
        當你要強調一系列相關的產品對象的設計以便進行聯合使用時。 
        當你提供一個產品類庫,而只想顯示它們的接口而不是實現時。 


3.建造者模式 


意圖 
將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。 


適用性 
    當創建複雜對象的算法應該獨立於該對象的組成部分以及它們的裝配方式時。 
    當構造過程必須允許被構造的對象有不同的表示時。 


4.工廠方法模式 


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


適用性 
    當一個類不知道它所必須創建的對象的類的時候。 
    當一個類希望由它的子類來指定它所創建的對象的時候。 
    當類將創建對象的職責委託給多個幫助子類中的某一個,並且你希望將哪一個幫助子類是代 
    理者這一信息局部化的時候。 


5.原型模式 


意圖 
用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。 


適用性 


    當要實例化的類是在運行時刻指定時,例如,通過動態裝載;或者 
    爲了避免創建一個與產品類層次平行的工廠類層次時;或者 
    當一個類的實例只能有幾個不同狀態組合中的一種時。建立相應數目的原型並克隆它們可能 
    比每次用合適的狀態手工實例化該類更方便一些。 


二.結構型模式 
6.適配器模式 


意圖 
將一個類的接口轉換成客戶希望的另外一個接口。Adapter模式使得原本由於接口不兼容而不能一起 
工作的那些類可以一起工作。 


適用性 
    你想使用一個已經存在的類,而它的接口不符合你的需求。 
    你想創建一個可以複用的類,該類可以與其他不相關的類或不可預見的類(即那些接口可能 
    不一定兼容的類)協同工作。 
     (僅適用於對象Adapter)你想使用一些已經存在的子類,但是不可能對每一個都進行子類 
    化以匹配它們的接口。對象適配器可以適配它的父類接口。 


7.橋接模式 


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


適用性 
    你不希望在抽象和它的實現部分之間有一個固定的綁定關係。例如這種情況可能是因爲,在 
    程序運行時刻實現部分應可以被選擇或者切換。 
    類的抽象以及它的實現都應該可以通過生成子類的方法加以擴充。這時Bridge模式使你可以 
    對不同的抽象接口和實現部分進行組合,並分別對它們進行擴充。 
    對一個抽象的實現部分的修改應對客戶不產生影響,即客戶的代碼不必重新編譯。 
    有許多類要生成。這樣一種類層次結構說明你必須將一個對象分解成兩個部分。 
    你想在多個對象間共享實現(可能使用引用計數),但同時要求客戶並不知道這一點。 


8.組合模式 


意圖 
將對象組合成樹形結構以表示“部分-整體”的層次結構。Composite                  使得用戶對單個對象和組合對象 
的使用具有一致性。 


適用性 
    你想表示對象的部分-整體層次結構。 
    你希望用戶忽略組合對象與單個對象的不同,用戶將統一地使用組合結構中的所有對象。 


9.裝飾模式 


意圖 
動態地給一個對象添加一些額外的職責。就增加功能來說,Decorator模式相比生成子類更爲靈活。 


適用性 
    在不影響其他對象的情況下,以動態、透明的方式給單個對象添加職責。 
    處理那些可以撤消的職責。 
    當不能採用生成子類的方法進行擴充時。一種情況是,可能有大量獨立的擴展,爲支持每一 
    種組合將產生大量的子類,使得子類數目呈爆炸性增長。另一種情況可能是因爲類定義被隱藏, 
    或類定義不能用於生成子類。 


10.外觀模式 


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


適用性 
    當你要爲一個複雜子系統提供一個簡單接口時。子系統往往因爲不斷演化而變得越來越復 
    雜。大多數模式使用時都會產生更多更小的類。這使得子系統更具可重用性,也更容易對子系 
    統進行定製,但這也給那些不需要定製子系統的用戶帶來一些使用上的困難。Facade可以提供 
    一個簡單的缺省視圖,這一視圖對大多數用戶來說已經足夠,而那些需要更多的可定製性的用 
    戶可以越過Facade層。 
    客戶程序與抽象類的實現部分之間存在着很大的依賴性。引入Facade 將這個子系統與客戶 
    以及其他的子系統分離,可以提高子系統的獨立性和可移植性。 


    當你需要構建一個層次結構的子系統時,使用Facade模式定義子系統中每層的入口點。如果 
    子系統之間是相互依賴的,你可以讓它們僅通過Facade 進行通訊,從而簡化了它們之間的依賴 
    關係。 


11.享元模式 


意圖 
運用共享技術有效地支持大量細粒度的對象。 
適用性 
    一個應用程序使用了大量的對象。 
    完全由於使用大量的對象,造成很大的存儲開銷。 
    對象的大多數狀態都可變爲外部狀態。 
    如果刪除對象的外部狀態,那麼可以用相對較少的共享對象取代很多組對象。 
    應用程序不依賴於對象標識。由於Flyweight對象可以被共享,對於概念上明顯有別的對象, 
    標識測試將返回真值。 


12.代理模式 


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


適用性 
    在需要用比較通用和複雜的對象指針代替簡單的指針的時候,使用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.職責鏈模式 


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


適用性 
    有多個的對象可以處理一個請求,哪個對象處理該請求運行時刻自動確定。 
    你想在不明確指定接收者的情況下,向多個對象中的一個提交一個請求。 
    可處理一個請求的對象集合應被動態指定。 


14.命令模式 


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


適用性 
    使用命令模式作爲"CallBack"在面向對象系統中的替代。"CallBack"講的便是先將一個函數 
    登記上,然後在以後調用此函數。 
    需要在不同的時間指定請求、將請求排隊。一個命令對象和原先的請求發出者可以有不同的 
    生命期。換言之,原先的請求發出者可能已經不在了,而命令對象本身仍然是活動的。 
    這時命令的接收者可以是在本地,也可以在網絡的另外一個地址。命令對象可以在串形化之後 
傳送到另外一臺機器上去。 
    系統需要支持命令的撤消(undo)。命令對象可以把狀態存儲起來,等到客戶端需要撤銷命令 
所產生的效果時,可以調用undo()方法,把命令所產生的效果撤銷掉。命令對象還可以提供redo() 
方法,以供客戶端在需要時,再重新實施命令效果。 
    如果一個系統要將系統中所有的數據更新到日誌裏,以便在系統崩潰時,可以根據日誌裏讀 
回所有的數據更新命令,重新調用Execute()方法一條一條執行這些命令,從而恢復系統在崩潰前所 
做的數據更新。 
    一個系統需要支持交易(Transaction)。一個交易結構封裝了一組數據更新命令。使用命令 
模式來實現交易結構可以使系統增加新的交易類型。 


15.解釋器模式 




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


適用性 
    當有一個語言需要解釋執行, 並且你可將該語言中的句子表示爲一個抽象語法樹時,可使用 
    解釋器模式。而當存在以下情況時該模式效果最好: 
    該文法簡單對於複雜的文法, 文法的類層次變得龐大而無法管理。此時語法分析程序生成器 
    這樣的工具是更好的選擇。它們無需構建抽象語法樹即可解釋表達式, 這樣可以節省空間而且 
    還可能節省時間。 
    效率不是一個關鍵問題最高效的解釋器通常不是通過直接解釋語法分析樹實現的, 而是首 
    先將它們轉換成另一種形式。例如,正則表達式通常被轉換成狀態機。但即使在這種情況下, 轉 
    換器仍可用解釋器模式實現, 該模式仍是有用的。 


16.迭代器模式 


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


適用性 
    訪問一個聚合對象的內容而無需暴露它的內部表示。 
    支持對聚合對象的多種遍歷。 
    爲遍歷不同的聚合結構提供一個統一的接口(即, 支持多態迭代)。 


17.中介者模式 


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


適用性 
    一組對象以定義良好但是複雜的方式進行通信。產生的相互依賴關係結構混亂且難以理解。 
    一個對象引用其他很多對象並且直接與這些對象通信,導致難以複用該對象。 
    想定製一個分佈在多個類中的行爲,而又不想生成太多的子類。 


18.備忘錄模式 


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


適用性 
    必須保存一個對象在某一個時刻的(部分)狀態, 這樣以後需要時它才能恢復到先前的狀態。 
    如果一個用接口來讓其它對象直接得到這些狀態,將會暴露對象的實現細節並破壞對象的封 
    裝性。 


19.觀察者模式 




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


適用性 
    當一個抽象模型有兩個方面, 其中一個方面依賴於另一方面。將這二者封裝在獨立的對象中 
    以使它們可以各自獨立地改變和複用。 
    當對一個對象的改變需要同時改變其它對象, 而不知道具體有多少對象有待改變。 
    當一個對象必須通知其它對象,而它又不能假定其它對象是誰。換言之, 你不希望這些對象 
    是緊密耦合的。 


20.狀態模式 


意圖 
允許一個對象在其內部狀態改變時改變它的行爲。對象看起來似乎修改了它的類。 


適用性 
    一個對象的行爲取決於它的狀態, 並且它必須在運行時刻根據狀態改變它的行爲。 
    一個操作中含有龐大的多分支的條件語句,且這些分支依賴於該對象的狀態。這個狀態通常 
    用一個或多個枚舉常量表示。通常, 有多個操作包含這一相同的條件結構。State模式將每一個 
    條件分支放入一個獨立的類中。這使得你可以根據對象自身的情況將對象的狀態作爲一個對象, 
    這一對象可以不依賴於其他對象而獨立變化。 


21.策略模式 


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


適用性 
    許多相關的類僅僅是行爲有異。策略提供了一種用多個行爲中的一個行爲來配置一個類 
    的方法。 


    需要使用一個算法的不同變體。例如,你可能會定義一些反映不同的空間/時間權衡的算法。 
    當這些變體實現爲一個算法的類層次時[ H O 8 7 ] ,可以使用策略模式。 
    算法使用客戶不應該知道的數據。可使用策略模式以避免暴露覆雜的、與算法相關的數據結 
    構。 
    一個類定義了多種行爲, 並且這些行爲在這個類的操作中以多個條件語句的形式出現。將相 
    關的條件分支移入它們各自的Strategy類中以代替這些條件語句。 


22.模版方法 


意圖 
定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。Template Method 使得子類可以不改 
變一個算法的結構即可重定義該算法的某些特定步驟。 


適用性 
    一次性實現一個算法的不變的部分,並將可變的行爲留給子類來實現。 
    各子類中公共的行爲應被提取出來並集中到一個公共父類中以避免代碼重複。這是Opdyke 


    和Johnson所描述過的重分解以一般化的一個很好的例子[ O J 9 3 ]。首先識別現有代碼 
    中的不同之處,並且將不同之處分離爲新的操作。最後,用一個調用這些新的操作的模板方法 
    來替換這些不同的代碼。 
    控制子類擴展。模板方法只在特定點調用hook操作,這樣就只允許在這些點進行擴展。 


23.訪問者模式 


意圖 
表示一個作用於某對象結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用 
於這些元素的新操作。 


適用性 
    一個對象結構包含很多類對象,它們有不同的接口,而你想對這些對象實施一些依賴於其具 
    體類的操作。 
    需要對一個對象結構中的對象進行很多不同的並且不相關的操作,而你想避免讓這些操作 
    污染這些對象的類。Visitor使得你可以將相關的操作集中起來定義在一個類中。當該對象結 
    構被很多應用共享時,用Visitor模式讓每個應用僅包含需要用到的操作。 
    定義對象結構的類很少改變,但經常需要在此結構上定義新的操作。改變對象結構類需要重 
    定義對所有訪問者的接口,這可能需要很大的代價。如果對象結構類經常改變,那麼可能還是 
    在這些類中定義這些操作較好。 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章