設計模式概念 引用《設計模式-可復用的面相對像設計》對模式的定義是這樣的:【Christopher Alexander 說過: “每一個模式描述了一個在我們周圍不斷重覆發生的問題,以及該問題的解決方案的核心。這樣,你就能一次又一次地使用該方案而不必做重覆勞動”, 儘管Alexander所指的是城市和 ...
設計模式概念
引用《設計模式-可復用的面相對像設計》對模式的定義是這樣的:【Christopher Alexander 說過: “每一個模式描述了一個在我們周圍不斷重覆發生的問題,以及該問題的解決方案的核心。這樣,你就能一次又一次地使用該方案而不必做重覆勞動”, 儘管Alexander所指的是城市和建築模式,但他的思想也同樣適用於面向對象設計模式,只是在面向對象的解決方案里,我們用對象和介面代替了牆壁和門窗。兩類模式的核心都在於提供了相關問題的解決方案。】
通俗的講設計模式就是解決一類問題的解決方案,具有一定的普遍性,在碰到特定問題的時候使用特定的模式就能完美的解決,說白了設計模式就是解決特定問題的一系列套路。在面向對象軟體設計中設計模式是解決特定設計問題的一系列方案或者說“套路”。這一系列解決方案是前輩們經過無數次的實踐總結傳承下來的寶貴經驗,我們這些後來者可以直接學習前人的經驗並應用到實際的工作中。一個模式應具有以下四個要素:
1. 模式名稱(pattern name),它用幾個簡單的詞語描述模式的問題,解決方案和效果。模式的名稱有助於我們理解,記憶和交流,模式是建立在較高抽象層次的設計。通常模式名稱更易於在實際項目中進行交流,模式名稱可以增強設計辭彙(設計語言)。如果不適用模式辭彙我們在交流一個設計的時候會顯得語言表達力不強,不夠簡潔甚至浪費時間,如果使用模式的辭彙,交流時語言的表達力更強,有點像漢語中的成語,成語有更強的表達力。 舉個例子:”我們要創建一個類來記錄所有用戶對這個模塊的訪問量,並且這個類在我們的正系統中有且只有一個實例“,說了這麼多其實就是“單例模式”, 我們換成模式辭彙表達就會更簡潔更富有表達力“在這裡我們使用【單例模式】”。
2.問題(problem) 描述了應該在何時使用模式。它解釋了設計問題和問題存在的前因後果,它可能描述了特定的設計問題,如怎樣用對象表示演算法等。也可能描述了導致不靈活設計的類或對象結構。有時候,問題部分會包括使用模式必須滿足的一系列先決條件。
3.解決方案(solution) 描述了設計的組成成分,它們之間的相互關係及各自的職責和協作方式。因為模式就像一個模板,可應用於多種不同場合,所以解決方案並不描述一個特定而具體的設計或實現,而是提供設計問題的抽象描述和怎樣用一個具有一般意義的元素組合(類或對象組合)來解決這個問題。
4.效果(consequences) 描述了模式應用的效果及使用模式應權衡的問題。儘管我們描述設計決策時,並不總提到模式效果,但它們對於評價設計選擇和理解使用模式的代價及好處具有重要意義。
設計模式分類
設計模式有兩種分類方法:根據目的分(模式用來完成什麼工作)和根據作用的範圍來分(模式主要用於類上還是主要用於對象上)。
1.根據目的可分為:創建型 (Creational)、創建型 (Creational)、 和行為型(Behavioral)三種。創建型模式與對象的創建有關;結構型模式處理類或對象的組合;行為型模式對類或象怎樣交互和怎樣分配職責進行描述。
2.根據範圍分為:類模式和對象模式。類模式處理類和子類之間的關係,這些關係通過繼承建立,是靜態的,在編譯時刻便確定下來了。對象模式處理對象間的關係,這些關係在運行時刻是可以變化的,更具動態性。從某種意義上來說,幾乎所有模式都使用繼承機制,所以“類模式”只指那些集中於處理類間關係的模式,而大部分模式都屬於對象模式的範疇。
設計模式分類:
目的 | ||||
創建型 (Creational) | 創建型 (Creational) | 行為型(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.實現模式中對應角色的代碼。
這乍看起來有些程式化,是的,這是針對初學這的一個引導思路。在實際使用中可不是這樣的,如果這麼生搬硬套的話,最後會發現很多設計模式不是被誤用就是被濫用,變成了為了模式而模式,如果這樣設計模式不但不能很好的解決設計問題反而成了將代碼變得複雜難以理解難以維護的罪魁禍首。通常不要去模式優先而應該是業務優先遵守面向對象的設計原則,按照設計原則去組織,設計介面類以及其依賴關係,再通過重構自然就會得到模式。
學習設計模式更重要的是從前人的總結中汲取經驗,學習設計模式要循序漸進,通過學習,模仿到靈活運用再到為自己的設計尋找靈感提高自身的設計能力。