前言
收錄一些本身在開發過程當中比較經常使用的模式,整理出來以便本身複習,畢竟熟才能生巧,才能變通,觸類旁通。
設計模式在大多數靈活性好、可擴展性高、可移植的優秀程序中都有運用,好比界面展示層運用的MVC模式的主要關係就是由Observer(View-Model)、Composite(CompositeView嵌套視圖)和Strategy(View-Controller)三個設計模式給出的。下面只列出模式的脈絡大綱,若是想再拓展開且有時間的能夠把經典磚頭《設計模式》多嚼幾遍。若是想了解個入門的,也能夠看下《大話設計模式》。
目錄
圖示符號說明html
生成器(Builder)算法
模板方法(Template Method)設計模式
觀察者模式(Observer)安全
中介者(Mediator)數據結構
單件(Singleton)函數
工廠方法(Factory Method)性能
抽象工廠(Abstract Factory)網站
組成(Composite)ui
裝飾(Decorator)spa
橋接(Bridge)
迭代器(Iterator)
一 、圖示符號說明
1.類圖
2.對象圖
2、生成器(Builder)
將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。
結構
參與者
爲建立一個Product對象的各個部件指定抽象接口。
實現Builder的接口以構造和裝配該產品的各個部件。
定義並明確它所建立的表示。
提供一個檢索產品的接口。
構造一個使用Builder接口的對象。
表示被構造的複雜對象。ConcreteBuilder建立該產品的內部表示並定義它的裝配過程。
包含定義組成部件的類,包括將這些部件裝配成最終產品的接口。
協做
- 客戶建立Director對象,並用它想要的Builder對象進行配置。
- 一旦產品部件被生成,導向器就會通知生成器。
- 生成器處理導向器的請求,並將部件添加到該產品中。
- 客戶從生成器中檢索產品。

效果
- 它使你能夠改變一個產品的內部表示:Builder對象嚮導向器提供一個構建產品的抽象接口。
- 它將構建代碼和表示代碼分開:每一個子Builder包含了建立和裝配一個特定產品的全部代碼,而後不一樣的Director能夠複用它以在相同部件集合的基礎上構做不一樣的Product。
- 它使你可對構造過程進行更精細的控制:僅當產品完成時導向器才能從生成器中取回它。
實現
- 裝配和構造接口
- 產品沒有抽象類
- 在Builder缺省的方法爲空
Builder模式和Abstract Factory 類似,主要區別在於Builder模式着重於一步步構建一個複雜對象,在最後一步返回產品,而Abstract Factory着重於多個系列的產品對象,產品是當即返回的。
3、模板方法(Template Method)
定義一個操做中算法的骨架,而將一些步驟延遲到子類中。Template Method使得子類能夠不改變一個算法的結構便可重定義該算法的某些特定步驟。
(模板方法:在方法體中一次性實現一個算法的不變部分,將可變的行爲留給子類實現。)
結構
參與者
定義抽象的原語操做(primitive operation),具體的子類將重定義它們以實現一個算法的各步驟。
實現一個模板方法,定義一個算法的骨架。該模板方法不只調用原語操做,也調用定義在AbstractClass或其餘對象中的操做。
實現原語操做以完成算法中與特定子類相關的步驟。
協做
ConcreteClass靠AbstractClass來實現算法中不變的步驟。
效果
模板方法應該指明那些操做是鉤子操做(能夠被重定義)以及哪些是抽象操做(必須被重定義),子類編寫者必須明確瞭解哪些操做是設計爲有待重定義的。
相關模式
Factory Method:在子類現象的函數中常常調用Factory Method。
模板方法使用繼承來改變算法的一部分,Strategy使用委託來改變整個算法。
4、觀察者模式(Observer)
定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,全部依賴於它的對象都會獲得通知並被自動更新。
結構
參與者
目標知道它的觀察者。能夠有任意多個觀察者觀察同一個目標。
提供註冊和刪除觀察者對象的接口。
爲那些在目標發生改變時需得到通知的對象定義一個更新接口。
將有關狀態存入各ConcreteObserver對象。
當它的狀態發生改變時,向它的各個觀察者發出通知。
維護一個指向ConcreteSubject對象的引用。
存儲有關狀態,這些狀態應與目標的狀態保持一致。
實現Observer的更新接口以使自身狀態與目標的狀態保持一致。
協做
優缺點
- 目標和觀察者間的抽象耦合;
- 支持廣播通訊
- 意外的更新
實現
- 建立目標到觀察者之間的映射:當目標不少而觀察者較少時,能夠用hash表作映射關聯。
- 觀察多個目標:一個觀察者依賴於多個目標時,目標對象能夠將本身做爲Update()操做的一個參數,讓觀察者知道應該去檢查哪個目標。屢次連續操做效率低。
- 誰觸發更新:一 在目標對象的SetState()(狀態設定操做)中改變目標對象狀態後自動調用Notify;二 讓客戶本身一系列操做更改完後在目標對象上調用Notify。客戶可能會忘記調用,容易出錯。
- 在觀察者中避免對已刪除目標的懸掛引用。當一個目標被刪除時,讓它通知它的觀察者將該目標的引用復位。
- 在發出通知前確保目標的狀態自身是一致的。
- 避免特定於觀察者的更新協議——推/拉模型
- 顯示地指定感興趣的改變(Aspect& interest)
- 封裝複雜的更新語義(更改管理器ChangeManager)
ChangeManager充當目標和觀察者之間的中介者(Mediator模式),可以使用Singleton模式來保證它是惟一的而且是可全局訪問的。

9. 結合目標類和觀察者類(在不支持多重繼承的語言中使用)
5、中介者(Mediator)
用一箇中介對象來封裝一系列的對象交互。中介者使各對象不須要顯示地相互引用,從而使其耦合鬆散,並且能夠獨立地改變它們之間的交互。
(中介者充當一箇中介以使組中的對象再也不相互顯示引用。這些對象僅知道中介者,從而減小了相互鏈接的數目。)
結構
參與者
中介者定義一個接口用於與各同事(Colleague)對象通訊。
具體中介者經過協調各同事對象實現協做行爲。
瞭解並維護它的各個同事。
每個同事類都知道它的中介者對象。
每個同事對象在需與其餘的同事通訊的時候,與它的中介者通訊。
協做
同事向一箇中介者對象發送和接收請求。中介者在各同事間適當地轉發請求以實現協做行爲。
相關模式
Colleague可以使用Observer模式與Mediator通訊。
6、單件(Singleton)
保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。
結構
參與者
定義一個Instance操做,容許客戶訪問它的惟一實例。Instance是一個類操做。
可能負責建立它本身的惟一實例。
協做
客戶只能經過Singleton的Instance操做訪問一個Singleton的實例。
優勢
- 對惟一實例的受控訪問
- 縮小名空間,避免那些存儲惟一實例的全局變量污染名空間
- 容許對操做和表示的精化:Singleton類能夠有子類。
- 容許可變數目的實例:這個模式使得你易於改變你的想法,並容許Singleton類有多個實例。此外,你能夠用相同的方法來控制應用所使用的實例數目。
- 比類操做更靈活
(惰性初始化:它的返回值直到被第一次訪問時才建立和保存)
實現
保證一個惟一的實例:經常使用的方法是將建立這個實例的操做隱藏在一個類操做,如經過靜態成員函數做爲全局訪問點公佈出去。
建立Singleton類的子類:指向單件實例的變量必須用子類的實例初始化,方法有三種
- 在Singleton的Instance操做中決定你要使用的是哪個單件。
- 將Instance的實現從父類中分離出來在子類中實現。
- 使用一個靜態的單件註冊表,根據名字,單件實例鍵值對進行存儲,在子類中註冊供。比前面兩種靈活。
7、工廠方法(Factory Method)
定義一個用於建立對象的接口,讓子類決定將哪個類實例化,Factory Method使一個類的實例化延遲到其子類。
結構
參與者
聲明工廠方法,該方法返回一個Product類型的對象。Creator也能夠定義一個工廠方法的缺省實現,它返回一個缺省的ConcreteProduct對象。
能夠調用工廠方法以建立一個Product對象。
重定義工廠方法以返回一個ConcreteProduct實例。
協做
Creator依賴於它的子類來定義工廠方法,以返回一個適當的ConcreteProduct實例。
相關模式
- Abstract Factory常常用工廠方法來實現(抽象工廠中的工廠能夠理解爲工廠方法,至關於集合多個工廠方法);
- 工廠方法一般在Template Methods模式中被調用(一個方法能夠同時是工廠方法和模板方法);
8、抽象工廠(Abstract Factory)
提供一個建立一系列相關或相互依賴對象的接口,而無需指定它們具體的類。
客戶僅與抽象類定義的接口交互,而不使用特定的具體類的接口
結構
參與者
聲明一個建立抽象產品對象的操做接口。
實現建立具體產品對象的操做。
爲一類產品對象聲明一個接口。
定義一個將被相應的具體工廠建立的產品對象。
實現AbstractProduct接口。
僅使用由AbstractFactory和AbstractProduct類聲明的接口。
協做
一般在運行時刻建立一個ConcreteFactory類的實例。這一具體的工廠建立具備特定實現的產品對象。爲建立不一樣的產品對象。客戶應使用不一樣的具體工廠。
Abstract Factory將產品對象的建立延遲到它的ConcreteFactory子類。
優缺點
- 它分離了具體的類:客戶經過工廠和產品的抽象接口操縱它們的實例。
- 它使得易於交換產品系列:一個具體工廠類在一個應用中僅出現一次,即在它初始化的時候,這使得改變一個應用的具體工廠變得容易。
- 它有利於產品的一致性:當一個系列的產品對象被設計在一塊兒工做時,一個應用一次只能使用同一系列的產品對象。
- 難以支持新種類的產品:支持新產品就須要擴展工廠接口,這將涉及Abstract Factory類和全部子類的改變。解決方案:
實現
- 將工做做爲單件:一個應用中通常只需一個具體工廠(產品系列)
- 建立產品:使用工廠方法(Factory Method)實現。多個產品系列時能夠考慮使用原型模式(Prototype),具體工廠使用產品系列中每個產品的原型實例來初始化,且它經過複製它的原型來建立新的產品。在基於原型的方法中,使得不是每一個新的產品系列都須要一個新的具體工廠類。
9、組成(Composite)
將對象組合成樹形結構以表示「部分-總體」的層次關係。Composite使得用戶對單個對象和組合對象的使用具備一致性。
結構
參與者
爲組合中的對象聲明接口。
在適當的狀況下,實現全部類共有接口的缺省行爲。
聲明一個接口用於訪問和管理Component的子組件。
(可選)在遞歸結構中定義一個接口,用於訪問一個父部件,並在合適的狀況下實現它。
在組合中表示葉節點對象,葉節點沒有子節點。
在組合中定義圖元對象的行爲。
定義有子部件的那些部件的行爲。
存儲子部件。
在Component接口中實現與子部件有關的操做。
經過Component接口操縱組合部件的對象。
協做
用戶使用Component類接口與組合結構中的對象進行交互。若是接收者是一個葉節點,則直接處理請求。若是接收者是Composite,它一般將請求發給它的子部件,在轉發請求以前或以後可能執行一些輔助操做。
實現
- 顯式的父部件引用,同時父部件引用也應支持Chain of Responsibility模式。
- 共享組件:與Flyweight模式共同使用。
- 最大化Component接口:Component類儘量涵蓋Leaf和Composite類的公共操做。
- 聲明管理子部件的操做:在透明性和安全性中做權衡,說明如上圖。
- 在基類Component中實現一個Component列表:只有當該結構中子類的數目相對較少時,才值得使用這種方法。不然對葉節點來講會致使空間浪費。
- 子部件排序:可以使用terator模式。
- 使用高速緩衝存貯改善性能:緩衝存儲經常使用信息。
- 應該由誰刪除Component:最好由Composite類負責刪除其子節點。但有一種狀況除外,即Leaf對象不會改變,所以能夠被共享。
- 存貯組件組好用哪種數據結構
相關模式
子部件-父部件鏈接用Chain of Responsibility模式
Composite模式常常和Decorator模式一塊兒使用
Flyweight讓你共享組件,但再也不能引用他們的父部件
Itertor可用來遍歷Composite
Visitor將原本應該分佈在Composite和Leaf類中的操做和行爲局部化
10、裝飾(Decorator)
動態地給一個對象添加一些額外的職責。就增長功能來講,Decorator模式相比生成子類方式更爲靈活。
結構
參與者
維持一個指向Component對象的指針,並定義一個與Component接口一致的接口。
協做
Decorator將請求轉發給它的Component對象,並有可能在轉發請求先後執行一些附加的動做。
優缺點
- 比靜態繼承更靈活:能夠在運行時增長和刪除裝飾。
- 避免在層次結構高層的類有太多的特徵:經過從簡單的部件開始,逐步組合出複雜的功能。
- Decorator和它的Component不同:一個被裝飾的組件和這個組件是有差異的,所以不能採用對象標識去做爲判斷的依據(不依賴對象標識)。
- 有許多小對象
實現
- 接口的一致性:裝飾對象的接口必須與它所裝飾的Component的接口是一致的。
- 省略抽象的Decorator類:當僅須要添加一個職責時,能夠把Decorator向Component轉發請求的職責合併到惟一的ConcreteDecorator中。
- 保持Component類的簡單性
- 改變對象的外殼(採用Decorator模式)與改變對象的內核(採用Strategy模式)
採用Strategy模式
11、橋接(Bridge)
將抽象部分與它的實現部分分離,使它們均可以獨立地變化。
結構
參與者
定義抽象類的接口。
維護一個指向Implementor類型對象的指針。
擴充由Abstraction定義的接口。
定義實現類的接口,該接口不必定要與Abstraction的接口徹底一致;事實上這兩個接口能夠徹底不一樣。通常來說,Impementor接口僅提供基本操做,而Abstraction則定義了基於這些基本操做的較高層次的操做。
實現Implementor接口並定義它的具體實現。
協做
Abstraction將Client的請求轉發給它的Implementor對象。
優勢
分離接口及其實現部分
提升可擴充性
實現細節對客戶透明
12、迭代器(Iterator)
提供一種方法順序訪問一個聚合對象中各個元素,而又不需暴露該對象的內部表示。
結構

參與者
迭代器定義訪問和遍歷元素的接口。
具體迭代器實現迭代器接口。
對該聚合遍歷時跟蹤當前位置。
聚合定義建立相應迭代器對象的接口。
具體聚合實現建立相應迭代器的接口,該操做返回ConcreteIterator的一個適當的實例。
協做
ConcreteIterator跟蹤聚合中的當前對象,並能計算出待遍歷的後續對象。
效果
它支持以不一樣的方式遍歷一個聚合:複雜的聚合可使用多種方式進行遍歷。
迭代器簡化了聚合的接口:有了迭代器的遍歷接口,聚合自己就再也不須要相似的遍歷接口了。
在同一個聚合上能夠同時有多個遍歷
實現
誰控制該迭代:當使用該迭代器的客戶來控制迭代時,該迭代器稱爲一個外部迭代器(推薦)。而當由迭代器控制迭代時,該迭代器稱爲一個內部迭代器。
外部迭代器:var aIterator=aList.CreateIterator();
for(altertor.First();altertor.IsDone();altertor.Next()){.....}
內部迭代器:var aTraverser=new Traverser(aList); //aTraverser內部已經包含了aIterator,在aTraverser內部對aList進行遍歷
aTraverser.Traverse();
誰定義遍歷算法:由迭代器負責(推薦),或由聚合自己負責,而後用迭代器(這時可稱爲遊標)來存儲當前迭代的狀態,指示當前位置。
附加的迭代器操做:迭代器的最小接口由First、Next、IsDone和CurrentItem操做組成。
相關模式
Composite:迭代器常被應用到像複合這樣的遞歸結構上。
FactoryMethod:多態迭代器靠Factory Method來實例化適當的迭代器子類。
Memento:常與迭代器模式一塊兒使用。迭代器可以使用一個memento來捕獲一個迭代的狀態。迭代器在其內部存儲memento。
相關資料: