引用《設計模式-可複用的面相對像設計》對模式的定義是這樣的:【Christopher Alexander 說過: 「每個模式描述了一個在咱們周圍不斷重複發生的問題,以及該問題的解決方案的核心。這樣,你就能一次又一次地使用該方案而沒必要作重複勞動」, 儘管Alexander所指的是城市和建築模式,但他的思想也一樣適用於面向對象設計模式,只是在面向對象的解決方案裏,咱們用對象和接口代替了牆壁和門窗。兩類模式的核心都在於提供了相關問題的解決方案。】html
通俗的講設計模式就是解決一類問題的解決方案,具備必定的廣泛性,在碰到特定問題的時候使用特定的模式就能完美的解決,說白了設計模式就是解決特定問題的一系列套路。在面向對象軟件設計中設計模式是解決特定設計問題的一系列方案或者說「套路」。這一系列解決方案是前輩們通過無數次的實踐總結傳承下來的寶貴經驗,咱們這些後來者能夠直接學習前人的經驗並應用到實際的工做中。一個模式應具備如下四個要素:算法
1. 模式名稱(pattern name),它用幾個簡單的詞語描述模式的問題,解決方案和效果。模式的名稱有助於咱們理解,記憶和交流,模式是創建在較高抽象層次的設計。一般模式名稱更易於在實際項目中進行交流,模式名稱能夠加強設計詞彙(設計語言)。若是不適用模式詞彙咱們在交流一個設計的時候會顯得語言表達力不強,不夠簡潔甚至浪費時間,若是使用模式的詞彙,交流時語言的表達力更強,有點像漢語中的成語,成語有更強的表達力。 舉個例子:」咱們要建立一個類來記錄全部用戶對這個模塊的訪問量,而且這個類在咱們的正系統中有且只有一個實例「,說了這麼多其實就是「單例模式」, 咱們換成模式詞彙表達就會更簡潔更富有表達力「在這裏咱們使用【單例模式】」。設計模式
2.問題(problem) 描述了應該在什麼時候使用模式。它解釋了設計問題和問題存在的來龍去脈,它可能描述了特定的設計問題,如怎樣用對象表示算法等。也可能描述了致使不靈活設計的類或對象結構。有時候,問題部分會包括使用模式必須知足的一系列先決條件。學習
3.解決方案(solution) 描述了設計的組成成分,它們之間的相互關係及各自的職責和協做方式。由於模式就像一個模板,可應用於多種不一樣場合,因此解決方案並不描述一個特定而具體的設計或實現,而是提供設計問題的抽象描述和怎樣用一個具備通常意義的元素組合(類或對象組合)來解決這個問題。ui
4.效果(consequences) 描述了模式應用的效果及使用模式應權衡的問題。儘管咱們描述設計決策時,並不總提到模式效果,但它們對於評價設計選擇和理解使用模式的代價及好處具備重要意義。spa
設計模式有兩種分類方法:根據目的分(模式用來完成什麼工做)和根據做用的範圍來分(模式主要用於類上仍是主要用於對象上)。設計
1.根據目的可分爲:建立型 (Creational)、結構型型 (Structural )、 和行爲型(Behavioral)三種。建立型模式與對象的建立有關;結構型模式處理類或對象的組合;行爲型模式對類或對象怎樣交互和怎樣分配職責進行描述。代理
2.根據範圍分爲:類模式和對象模式。類模式處理類和子類之間的關係,這些關係經過繼承創建,是靜態的,在編譯時刻便肯定下來了。對象模式處理對象間的關係,這些關係在運行時刻是能夠變化的,更具動態性。從某種意義上來講,幾乎全部模式都使用繼承機制,因此「類模式」只指那些集中於處理類間關係的模式,而大部分模式都屬於對象模式的範疇。日誌
設計模式分類:server
目的 | ||||
建立型 (Creational) | 結構型型 (Structural ) | 行爲型(Behavioral) | ||
範圍 | 類 | 工廠模式(Factory Method Pattern) | 適配器模式(Adapter Pattern)【類】 | 解釋器模式(In terpreter Pattern) |
簡單工廠模式(Simple Factory Method Pattern) | 模板方法模式(Template Method Pattern) | |||
對象 | 抽象工廠模式(Abstract Factory Pattern) | 適配器模式(Adapter Pattern)【對象】 | 職責鏈模式(Chain of Responsibility Pattern) | |
建造者模式(Builder Pattern) | 橋接模式(Bridge Pattern) | 命令模式(Command Pattern) | ||
單例模式(Singleton Pattern) | 組合模式(Composite Pattern) | 迭代器模式(Iterator Pattern) | ||
原型模式(Prototype Pattern) | 裝飾模式(Decorator Pattern) | 中介者模式(Mediator Pattern) | ||
外觀模式(Facade Pattern) | 備忘錄模式(Memento Pattern) | |||
享元模式(Flyweight Pattern) | 觀察者模式(Observer Pattern) | |||
代理模式(Proxy Pattern) | 狀態模式(State Pattern) | |||
策略模式(Strategy Pattern) | ||||
訪問者模式(Visitor) |
設計模式不是孤立存在的他們之間存在着千絲萬縷的聯繫。下面是GoF23個經典模式的關係:
GoF 23個經典設計模式的意圖:
1.工廠模式(Factory Method Pattern):定義一個用於建立對象的接口,讓子類決定將哪個類實例化。Factory Method使一個類的實例化延遲到其子類。
2.抽象工廠模式(Abstract Factory Pattern):提供一個建立一系列相關或相互依賴對象的接口,而無需指定它們具體的類。
3.建造者模式(Builder Pattern):將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。
4.單例模式(Singleton Pattern):保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。
5.原型模式(Prototype Pattern):用原型實例指定建立對象的種類,而且經過拷貝這個原型來建立新的對象。
6.適配器模式(Adapter Pattern):將一個類的接口轉換成客戶但願的另一個接口。 Adapter模式使得本來因爲接口不兼容而不能一塊兒工做的那些類能夠一塊兒工做。
7.橋接模式(Bridge Pattern):將抽象部分與它的實現部分分離,使它們均可以獨立地變化。
8.組合模式(Composite Pattern):將對象組合成樹形結構以表示「部分 -總體」的層次結構。 Composite使得客戶對單個對象和複合對象的使用具備一致性。
9.裝飾模式(Decorator Pattern):動態地給一個對象添加一些額外的職責。就擴展功能而言, Decorator模式比生成子類方式更爲靈活。
10.外觀模式(Facade Pattern):爲子系統中的一組接口提供一個一致的界面, Facade模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。
11.享元模式(Flyweight Pattern):運用共享技術有效地支持大量細粒度的對象。
12.代理模式(Proxy Pattern):爲其餘對象提供一個代理以控制對這個對象的訪問。
13.解釋器模式(In terpreter Pattern):給定一個語言 , 定義它的文法的一種表示,並定義一個解釋器 , 該解釋器使用該表示來解釋語言中的句子.
14.模板方法模式(Template Method Pattern):定義一個操做中的算法的骨架,而將一些步驟延遲到子類中。Template Method使得子類能夠不改變一個算法的結構便可重定義該算法的某些特定步驟。
15.職責鏈模式(Chain of Responsibility Pattern):爲解除請求的發送者和接收者之間耦合,而使多個對象都有機會處理這個請求。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理它。
16.命令模式(Command Pattern):將一個請求封裝爲一個對象,從而使你可用不一樣的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可取消的操做。
17.迭代器模式(Iterator Pattern):給定一個語言 , 定義它的文法的一種表示,並定義一個解釋器 , 該解釋器使用該表示來解釋語言中的句子。
18.中介者模式(Mediator Pattern):用一箇中介對象來封裝一系列的對象交互。中介者使各對象不須要顯式地相互引用,從而使其耦合鬆散,並且能夠獨立地改變它們之間的交。
19.備忘錄模式(Memento Pattern):在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象以外保存這個狀態。這樣之後就可將該對象恢復到保存的狀態。
20.觀察者模式(Observer Pattern):定義對象間的一種一對多的依賴關係 ,以便當一個對象的狀態發生改變時 ,全部依賴於它的對象都獲得通知並自動刷新。
21.狀態模式(State Pattern):用原型實例指定建立對象的種類,而且經過拷貝這個原型來建立新的對象。
22.策略模式(Strategy Pattern):定義一系列的算法 ,把它們一個個封裝起來 , 而且使它們可相互替換。本模式使得算法的變化可獨立於使用它的客戶。
23.訪問者模式(Visitor):表示一個做用於某對象結構中的各元素的操做。它使你能夠在不改變各元素的類的前提下定義做用於這些元素的新操做。
實際模式有不少光GoF的設計模式就一23中,那麼咱們在使用的過程當中怎麼去選擇使用那種設計模式呢?
1. 根據設計模式的意圖和目的去選擇使用設計模式。
2.根據問題的類型去尋找與模式匹配的解決類似問題的設計模式。
3.考慮實際中的變化的部分。封裝變化,那種模式更適合封裝對應變化或者說能將變化的點控制在更小的範圍內。
一旦你選擇了一個設計模式該怎麼使用呢?
1. 理解模式的意圖和效果,肯定選擇的模式適合解決你的問題。
2.弄明白模式代碼的組織結構。
3.弄明白模式參與者的角色。
4.建立模式中對應於你實際要解決問題的各個參與者和角色。
5.實現模式中對應角色的代碼。
這乍看起來有些程式化,是的,這是針對初學這的一個引導思路。在實際使用中可不是這樣的,若是這麼生搬硬套的話,最後會發現不少設計模式不是被誤用就是被濫用,變成了爲了模式而模式,若是這樣設計模式不但不能很好的解決設計問題反而成了將代碼變得複雜難以理解難以維護的罪魁禍首。一般不要去模式優先而應該是業務優先遵照面向對象的設計原則,按照設計原則去組織,設計接口類以及其依賴關係,再經過重構天然就會獲得模式。
學習設計模式更重要的是從前人的總結中汲取經驗,學習設計模式要按部就班,經過學習,模仿到靈活運用再到爲本身的設計尋找靈感提升自身的設計能力。