設計模式之23種模式

綜述

設計模式分爲三種類型,共23種。
  • 創建型模式:單例模式、抽象工廠模式、建造者模式、工廠模式、原型模式。
  • 結構型模式:適配器模式、橋接模式、裝飾模式、組合模式、外觀模式、享元模式、代理模式。
  • 行爲型模式:模版方法模式、命令模式、迭代器模式、觀察者模式、中介者模式、備忘錄模式、解釋器模式、狀態模式、策略模式、職責鏈模式、訪問者模式。
按字典序排列簡介如下。
Abstract Factory(抽象工廠模式):提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。
Adapter(適配器模式):將一個類的接口轉換成客戶希望的另外一個接口。Adapter模式使得原本由於接口不兼容而不能一起工作的那些類可以一起工作。
Bridge(橋接模式):將抽象部分與它的實現部分分離,使它們都可以獨立地變化。
Builder(建造者模式):將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。
Chain of Responsibility(職責鏈模式):爲解除請求的發送者和接收者之間耦合,而使多個對象都有機會處理這個請求。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理它。
Command(命令模式):將一個請求封裝爲一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可取消的操作。
Composite(組合模式):將對象組合成樹形結構以表示“部分-整體”的層次結構。它使得客戶對單個對象和複合對象的使用具有一致性。
Decorator(裝飾模式):動態地給一個對象添加一些額外的職責。就擴展功能而言, 它比生成子類方式更爲靈活。
Facade(外觀模式):爲子系統中的一組接口提供一個一致的界面,Facade模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。
Factory Method(工廠模式):定義一個用於創建對象的接口,讓子類決定將哪一個類實例化。Factory Method使一個類的實例化延遲到其子類。
Flyweight(享元模式):運用共享技術有效地支持大量細粒度的對象。
Interpreter(解析器模式):給定一個語言, 定義它的文法的一種表示,並定義一個解釋器, 該解釋器使用該表示來解釋語言中的句子。
Iterator(迭代器模式):提供一種方法順序訪問一個聚合對象中各個元素,而又不需暴露該對象的內部表示。
Mediator(中介模式):用一箇中介對象來封裝一系列的對象交互。中介者使各對象不需要顯式地相互引用,從而使其耦合鬆散,而且可以獨立地改變它們之間的交互。
Memento(備忘錄模式):在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態。這樣以後就可將該對象恢復到保存的狀態。
Observer(觀察者模式):定義對象間的一種一對多的依賴關係,以便當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並自動刷新。
Prototype(原型模式):用原型實例指定創建對象的種類,並且通過拷貝這個原型來創建新的對象。
Proxy(代理模式):爲其他對象提供一個代理以控制對這個對象的訪問。
Singleton(單例模式):保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。 單例模式是最簡單的設計模式之一,但是對於Java的開發者來說,它卻有很多缺陷。在九月的專欄中,David Geary探討了單例模式以及在面對多線程(multi-threading)、類裝載器(class loaders)和序列化(serialization)時如何處理這些缺陷。
State(狀態模式):允許一個對象在其內部狀態改變時改變它的行爲。對象看起來似乎修改了它所屬的類。
Strategy(策略模式):定義一系列的算法,把它們一個個封裝起來, 並且使它們可相互替換。本模式使得算法的變化可獨立於使用它的客戶。
Template Method(模板方法模式):定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。Template Method使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。
Visitor(訪問者模式):表示一個作用於某對象結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用於這些元素的新操作。
從下一節開始,詳細描述以下每一種設計模式。

工廠模式(Factory)

工廠模式(Factory)

工廠模式(Factory)

意圖
定義一個用於創建對象的接口,讓子類決定實例化哪一個類。Factory Method 使一個類的實例化延遲到其子類。
適用性
  • 當一個類不知道它所必須創建的對象的類的時候。
  • 當一個類希望由它的子類來指定它所創建的對象的時候。
  • 當類將創建對象的職責委託給多個幫助子類中的某一個,並且你希望將哪一個幫助子類是代理者這一信息局部化的時候。

抽象工廠模式(Abstract Factory)

抽象工廠模式(Abstract Factory)

抽象工廠模式(Abstract Factory)

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

建造者模式(Builder)

意圖
建造者模式

建造者模式

將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。
適用性
  • 當創建複雜對象的算法應該獨立於該對象的組成部分以及它們的裝配方式時。
  • 當構造過程必須允許被構造的對象有不同的表示時。

原型模式(Prototype)

意圖
原型模式

原型模式

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

單例模式(Singleton)

意圖
單例模式

單例模式

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

適配器模式(Adapter)

意圖
適配器模式

適配器模式

將一個類的接口轉換成另外一個客戶希望的接口。Adapter 模式使得原本由於接口不兼容而不能一起工作的那些類可以一起工作。
適用性
  • 你想使用一個已經存在的類,而它的接口不符合你的需求。
  • 你想創建一個可以複用的類,該類可以與其他不相關的類或不可預見的類(即那些接口可能不一定兼容的類)協同工作。
  • (僅適用於對象Adapter)你想使用一些已經存在的子類,但是不可能對每一個都進行子類化以匹配它們的接口。對象適配器可以適配它的父類接口。

橋接模式(Bridge)

意圖
橋接模式

橋接模式

將抽象部分與它的實現部分分離,使它們都可以獨立地變化。
適用性
  • 你不希望在抽象和它的實現部分之間有一個固定的綁定關係。例如這種情況可能是因爲,在程序運行時刻實現部分應可以被選擇或者切換。
  • 類的抽象以及它的實現都應該可以通過生成子類的方法加以擴充。這時B r i d g e 模式使你可以對不同的抽象接口和實現部分進行組合,並分別對它們進行擴充。
  • 對一個抽象的實現部分的修改應對客戶不產生影響,即客戶的代碼不必重新編譯。
  • C++)你想對客戶完全隱藏抽象的實現部分。在C++中,類的表示在類接口中是可見的。
  • 有許多類要生成。這樣一種類層次結構說明你必須將一個對象分解成兩個部分。Rumbaugh稱這種類層次結構爲“嵌套的普化”(nested generalizations )。
  • 你想在多個對象間共享實現(可能使用引用計數),但同時要求客戶並不知道這一點。一個簡單的例子便是Coplien的String類,在這個類中多個對象可以共享同一個字符串表示(StringRep)。

組合模式(Composite)

意圖
組合模式

組合模式

將對象組合成樹形結構以表示“部分-整體”的層次結構。C o m p o s i t e 使得用戶對單個對象和組合對象的使用具有一致性。
適用性
  • 你想表示對象的部分—整體層次結構。
  • 你希望用戶忽略組合對象與單個對象的不同,用戶將統一地使用組合結構中的所有對象。

裝飾模式(Decorator)

意圖
裝飾模式

裝飾模式

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

門面模式(Facade)

意圖
門面模式

門面模式

爲子系統中的一組接口提供一個一致的界面,Facade模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。
適用性
  • 當你要爲一個複雜子系統提供一個簡單接口時。子系統往往因爲不斷演化而變得越來越複雜。大多數模式使用時都會產生更多更小的類。這使得子系統更具可重用性,也更容易對子系統進行定製,但這也給那些不需要定製子系統的用戶帶來一些使用上的困難。Facade可以提供一個簡單的缺省視圖,這一視圖對大多數用戶來說已經足夠,而那些需要更多的可定製性的用戶可以越過Facade層。
  • 客戶程序與抽象類的實現部分之間存在着很大的依賴性。引入Facade將這個子系統與客戶以及其他的子系統分離,可以提高子系統的獨立性和可移植性。
  • 當你需要構建一個層次結構的子系統時,使用門面模式定義子系統中每層的入口點。如果子系統之間是相互依賴的,你可以讓它們僅通過Facade進行通訊,從而簡化了它們之間的依賴關係。

享元模式(Flyweight)

意圖
享元模式

享元模式

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

代理模式(Proxy)

意圖
代理模式

代理模式

爲其他對象提供一種代理以控制對這個對象的訪問。
適用性
在需要用比較通用和複雜的對象指針代替簡單的指針的時候,使用Proxy模式。下面是一 些可以使用Proxy模式常見情況:
  1. 遠程代理(Remote Proxy)爲一個對象在不同的地址空間提供局部代表。
  2. 虛代理(Virtual Proxy)根據需要創建開銷很大的對象。
  3. 保護代理(Protection Proxy)控制對原始對象的訪問。保護代理用於對象應該有不同 的訪問權限的時候。
  4. 智能指引(Smart Reference)取代了簡單的指針,它在訪問對象時執行一些附加操作。 它的典型用途包括:
    • 對指向實際對象的引用計數,這樣當該對象沒有引用時,可以自動釋放它(也稱爲SmartPointers)。
    • 當第一次引用一個持久對象時,將它裝入內存。
    • 在訪問一個實際對象前,檢查是否已經鎖定了它,以確保其他對象不能改變它。

職責鏈模式(Chain of Responsibility)

意圖
職責鏈模式

職責鏈模式

使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關係。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理它爲止。
適用性
  • 有多個的對象可以處理一個請求,哪個對象處理該請求運行時刻自動確定。
  • 你想在不明確指定接收者的情況下,向多個對象中的一個提交一個請求。
  • 可處理一個請求的對象集合應被動態指定。

命令模式(Command)

意圖
命令模式

命令模式

將一個請求封裝爲一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可取消的操作
適用性
  • 像上面討論的MenuItem對象那樣,抽象出待執行的動作以參數化某對象。你可用過程語言中的回調(callback)函數表達這種參數化機制。所謂回調函數是指函數先在某處註冊,而它將在稍後某個需要的時候被調用。Command模式是回調機制的一個面向對象的替代品。
  • 在不同的時刻指定、排列和執行請求。一個Command對象可以有一個與初始請求無關的生存期。如果一個請求的接收者可用一種與地址空間無關的方式表達,那麼就可將負責該請求的命令對象傳送給另一個不同的進程並在那兒實現該請求。
  • 支持取消操作。Command的Execute操作可在實施操作前將狀態存儲起來,在取消操作時這個狀態用來消除該操作的影響。Command接口必須添加一個Execute操作,該操作取消上一次Execute調用的效果。執行的命令被存儲在一個歷史列表中。可通過向後和向前遍歷這一列表並分別調用Unexecute和Execute來實現重數不限的“取消”和“重做”。
  • 支持修改日誌,這樣當系統崩潰時,這些修改可以被重做一遍。在Command接口中添加裝載操作和存儲操作,可以用來保持變動的一個一致的修改日誌。從崩潰中恢復的過程包括從磁盤中重新讀入記錄下來的命令並用Execute操作重新執行它們。
  • 用構建在原語操作上的高層操作構造一個系統。這樣一種結構在支持事務(Transaction)的信息系統中很常見。一個事務封裝了對數據的一組變動。Command模式提供了對事務進行建模的方法。Command有一個公共的接口,使得你可以用同一種方式調用所有的事務。同時使用該模式也易於添加新事務以擴展系統。

解析器模式(Interpreter)

意圖
解析器模式

解析器模式

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

迭代器模式(Iterator)

意圖
提供一種方法順序訪問一個聚合對象中各個元素, 而又不需暴露該對象的內部表示。
適用性
  • 訪問一個聚合對象的內容而無需暴露它的內部表示。
  • 支持對聚合對象的多種遍歷。
  • 爲遍歷不同的聚合結構提供一個統一的接口(即, 支持多態迭代)。

中介模式(Mediator)

意圖
中介模式

中介模式

用一箇中介對象來封裝一系列的對象交互。中介者使各對象不需要顯式地相互引用,從而使其耦合鬆散,而且可以獨立地改變它們之間的交互。
適用性
  • 一組對象以定義良好但是複雜的方式進行通信。產生的相互依賴關係結構混亂且難以理解。
  • 一個對象引用其他很多對象並且直接與這些對象通信,導致難以複用該對象。
  • 想定製一個分佈在多個類中的行爲,而又不想生成太多的子類。

備忘錄模式(Memento)

意圖
備忘錄模式

備忘錄模式

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

觀察者模式(Observer)

意圖
觀察者模式

觀察者模式

定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時, 所有依賴於它的對象都得到通知並被自動更新。
適用性
  • 當一個抽象模型有兩個方面, 其中一個方面依賴於另一方面。將這二者封裝在獨立的對象中以使它們可以各自獨立地改變和複用。
  • 當對一個對象的改變需要同時改變其它對象, 而不知道具體有多少對象有待改變。
  • 當一個對象必須通知其它對象,而它又不能假定其它對象是誰。換言之,你不希望這些對象是緊密耦合的。

狀態模式(State)

意圖
狀態模式

狀態模式

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

策略模式(Strategy)

意圖
策略模式

策略模式

定義一系列的算法,把它們一個個封裝起來, 並且使它們可相互替換。本模式使得算法可獨立於使用它的客戶而變化。
適用性
  • 許多相關的類僅僅是行爲有異。“策略”提供了一種用多個行爲中的一個行爲來配置一個類的方法。
  • 需要使用一個算法的不同變體。例如,你可能會定義一些反映不同的空間/時間權衡的算法。當這些變體實現爲一個算法的類層次時,可以使用策略模式。
  • 算法使用客戶不應該知道的數據。可使用策略模式以避免暴露覆雜的、與算法相關的數據結構
  • 一個類定義了多種行爲, 並且這些行爲在這個類的操作中以多個條件語句的形式出現。將相關的條件分支移入它們各自的Strategy類中以代替這些條件語句。

模版模式(Template)

意圖
模板模式

模板模式

定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。Te m p l a t e M e t h o d 使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。
適用性
  • 一次性實現一個算法的不變的部分,並將可變的行爲留給子類來實現。
  • 各子類中公共的行爲應被提取出來並集中到一個公共父類中以避免代碼重複。這是Opdyke和Johnson所描述過的“重分解以一般化”的一個很好的例子。首先識別現有代碼中的不同之處,並且將不同之處分離爲新的操作。最後,用一個調用這些新的操作的模板方法來替換這些不同的代碼。
  • 控制子類擴展。模板方法只在特定點調用“hook”操作,這樣就只允許在這些點進行擴展。

訪問者模式(Visitor)

意圖
訪問者模式

訪問者模式

表示一個作用於某對象結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用於這些元素的新操作。
適用性
  • 一個對象結構包含很多類對象,它們有不同的接口,而你想對這些對象實施一些依賴於其具體類的操作。
  • 需要對一個對象結構中的對象進行很多不同的並且不相關的操作,而你想避免讓這些操作“污染”這些對象的類。Visitor使得你可以將相關的操作集中起來定義在一個類中。當該對象結構被很多應用共享時,用Visitor模式讓每個應用僅包含需要用到的操作。
  • 定義對象結構的類很少改變,但經常需要在此結構上定義新的操作。改變對象結構類需要重定義對所有訪問者的接口,這可能需要很大的代價。如果對象結構類經常改變,那麼可能還是在這些類中定義這些操作較好。

5設計步驟編輯

綜述

如何把設計模式的採用和日益臨近的最後期限、緊縮的預算和很多公司現有的有限團隊資源相結合?以下是成功制訂設計模式的步驟。

強大的通信和培訓

許多機構擁有領先技術,可能正式通過了設計師論壇的論證或者非正式的公認專家。這些領先廠商將推廣設計模式採用中的開放通信,並將培訓開發具體設計模式的團隊。通信應當跨開發團隊和項目以便預先防止採用豎井和多種惟一的實現(謹記每個Developer/Project AntiPattern的實現)。培訓可以採用正式的internal lunch-and-learns、正式的internal class或者派一些員工參加外部培訓。這些培訓方式將促進正確的設計模式應用程序。如果僅有極少的觀衆能夠參加培訓,最佳的候選人是那些感覺適合在回來後能夠培訓其同事的人。

設計模式採用指導

設計模式可用於使項目受益,但是他們也可能因爲誤用而對應用程序造成損害。應當鼓勵採用他們,但是對其的採用應當受到審閱和驗證。設計模式可以包含在設計和開發過程中。在任何一種情況中,設計模式的使用應當由審閱者確認和驗證。在審閱過程中還可能會遇到這樣的情況,額外的設計模式不適用於最初包括的地方。即使環境中沒有進行正式的審閱,這一步驟也可以通過同事審閱或者團隊討論來完成。這一步驟中的審閱者要麼是主要團隊的成員,要麼與他們建立開放通信。
指導採用對於broad exposure類別的設計模式非常關鍵。這些設計模式具有很多相關的風險,因爲他們將創建依賴性。這些依賴性可能在一些對象類中,例如,只工作在更加廣泛的DAO設計模式實現範圍中的數據訪問對象(DAO)、或者跨應用程序邊界(如使用Value Object設計模式在應用程序和應用程序層之間傳輸數據)。這些設計模式也可以由項目中的其他人或者不同項目的人實現,而且實現應當重新使用,不同於創建另一種獨特的實現。

重用實現,不只是設計模式

只要在創建自己的設計模式實現中有一定的滿足,團隊和公司就可以在重用發生在代碼層時,而不是設計創意層時獲得更多益處。使企業獲益的最初設計模式是改進的實現。但是,真正的目標是重用實現。重用實現將導致:a)其他可重用的類(取決於公共實現);b)縮短開發時間和降低成本;c)縮短維護時間和降低成本;d)在應用程序之間和內部輕鬆集成。
這種重用對broad exposure設計模式非常重要(有時是基本的)。這些設計模式創建了外部依賴性(集成將從公共實現中受益)或者產生全部的自定義類庫(如果有公共基礎將可重用)。isolated use設計模式也可以從重用中獲益,但是如果他們是根據具體情況定製的,他們就非常難以重用。
有時您可能會問自己:“如果重用比較好,爲什麼設計模式和可以重用的實現不可以一同應用呢?”在我們討論設計模式如何使更多讀者獲益的時候纔會討論這個問題。如果可能,如果已經預定義了實現,那麼達到廣泛適用性這個目標就會非常困難。然而,一旦設計模式被應用到特殊的問題域或者技術基礎設施中,那麼就可以重用在該環境中產生的實現。

架構中的設計模式

這看起來像是一件可怕的任務,需要掌握設計模式如何應用在實際情況中,如何構建優質的實現,以及如何促進重用實現。完成該任務的方法之一就是在環境中引入應用程序架構。應用程序架構提供了應用程序需要的結構,從而使開發團隊可以關注應用程序的域邏輯。這包含了已實現的設計模式。除了重用設計模式概念或者單個實現之外,可以在多個項目和應用程序之間重用架構。這種共享的公共實現確保了兼容性,併爲開發和維護多種不同的實現提供了一種低成本替代方案。兼容性提供了重新使用需要的技術基礎。沒有足夠的篇幅在這裏深入討論架構的其他重要品質,如運行時監測和管理、可配置應用程序邏輯和適應性行爲等。您可以從Carnegie Mellon Software Engineering Institute 中學習到更多有關架構的知識。

6形象比喻編輯

抽象工廠模式(Abstract Factory)

追MM少不了請吃飯了,麥當勞的雞翅和肯德基的雞翅都是MM愛吃的東西,雖然口味有所不同,但不管你帶MM去麥當勞或肯德基,只管向服務員說“來四個雞翅”就行了。麥當勞和肯德基就是生產雞翅的Factory
工廠模式:客戶類和工廠類分開。消費者任何時候需要某種產品,只需向工廠請求即可。消費者無須修改就可以接納新產品。缺點是當產品修改時,工廠類也要做相應的修改。如:如何創建及如何向客戶端提供。

建造者模式(Builder)

MM最愛聽的就是“我愛你”這句話了,見到不同地方的MM,要能夠用她們的方言跟她說這句話哦,我有一個多種語言翻譯機,上面每種語言都有一個按鍵,見到MM我只要按對應的鍵,它就能夠用相應的語言說出“我愛你”這句話了,國外的MM也可以輕鬆搞定,這就是我的“我愛你 ”builder。(這一定比美軍在伊拉克用的翻譯機好賣)
建造者模式:將對象的內部表象和對象的生成過程分割開來,從而使一個建造過程生成具有不同的內部表象的產品對象。建造模式使得產品內部表象可以獨立的變化,客戶不必知道產品內部組成的細節。建造模式可以強制實行一種分步驟進行的建造過程。

工廠模式(Factory)

請MM去麥當勞吃漢堡,不同的MM有不同的口味,要每個都記住是一件煩人的事情,我一般採用Factory Method模式,帶着MM到服務員那兒,說“要一個漢堡”,具體要什麼樣的漢堡呢,讓MM直接跟服務員說就行了。
工廠方法模式:核心工廠類不再負責所有產品的創建,而是將具體創建的工作交給子類去做,成爲一個抽象工廠角色,僅負責給出具體工廠類必須實現的接口,而不接觸哪一個產品類應當被實例化這種細節。

原型模式(Prototype)

跟MM用QQ聊天,一定要說些深情的話語了,我搜集了好多肉麻的情話,需要時只要copy出來放到QQ裏面就行了,這就是我的情話prototype了。(100塊錢一份,你要不要)
原始模型模式:通過給出一個原型對象來指明所要創建的對象的類型,然後用複製這個原型對象的方法創建出更多同類型的對象。原始模型模式允許動態的增加或減少產品類,產品類不需要非得有任何事先確定的等級結構,原始模型模式適用於任何的等級結構。缺點是每一個類都必須配備一個克隆方法。

單例模式(Singleton)

俺有6個漂亮的老婆,她們的老公都是我,我就是我們家裏的老公Sigleton,她們只要說道“老公”,都是指的同一個人,那就是我(剛纔做了個夢啦,哪有這麼好的事)
單例模式:單例模式確保某一個類只有一個實例,而且自行實例化並向整個系統提供這個實例單例模式。單例模式只應在有真正的“單一實例”的需求時纔可使用。

適配器模式(Adapter)

在朋友聚會上碰到了一個美女Sarah,從香港來的,可我不會說粵語,她不會說普通話,只好求助於我的朋友kent了,他作爲我和Sarah之間的Adapter,讓我和Sarah可以相互交談了(也不知道他會不會耍我)
適配器(變壓器)模式:把一個類的接口變換成客戶端所期待的另一種接口,從而使原本因接口原因不匹配而無法一起工作的兩個類能夠一起工作。適配類可以根據參數返還一個合適的實例給客戶端。

橋接模式(Bridge)

早上碰到MM,要說早上好,晚上碰到MM,要說晚上好;碰到MM穿了件新衣服,要說你的衣服好漂亮哦,碰到MM新做的髮型,要說你的頭髮好漂亮哦。不要問我“早上碰到MM新做了個髮型怎麼說”這種問題,自己用BRIDGE組合一下不就行了
橋樑模式:將抽象化與實現化脫耦,使得二者可以獨立的變化,也就是說將他們之間的強關聯變成弱關聯,也就是指在一個軟件系統的抽象化和實現化之間使用組合/聚合關係而不是繼承關係,從而使兩者可以獨立的變化。

混合模式(Composite)

Mary今天過生日。“我過生日,你要送我一件禮物。”“嗯,好吧,去商店,你自己挑。”“這件T恤挺漂亮,買,這條裙子好看,買,這個包也不錯,買。”“喂,買了三件了呀,我只答應送一件禮物的哦。”“什麼呀,T恤加裙子加包包,正好配成一套呀,小姐,麻煩你包起來。 ”“……”,MM都會用Composite模式了,你會了沒有?
合成模式:合成模式將對象組織到樹結構中,可以用來描述整體與部分的關係。合成模式就是一個處理對象的樹結構的模式。合成模式把部分與整體的關係用樹結構表示出來。合成模式使得客戶端把一個個單獨的成分對象和由他們複合而成的合成對象同等看待。

裝飾模式(Decorator)

Mary過完輪到Sarly過生日,還是不要叫她自己挑了,不然這個月伙食費肯定玩完,拿出我2008年在華山頂上照的照片,在背面寫上“最好的的禮物,就是愛你的Fita”,再到街上禮品店買了個像框(賣禮品的MM也很漂亮哦),再找隔壁搞美術設計的Mike設計了一個漂亮的盒子裝起來……,我們都是Decorator,最終都在修飾我這個人呀,怎麼樣,看懂了嗎?
裝飾模式:裝飾模式以對客戶端透明的方式擴展對象的功能,是繼承關係的一個替代方案,提供比繼承更多的靈活性。動態給一個對象增加功能,這些功能可以再動態的撤消。增加由一些基本功能的排列組合而產生的非常大量的功能。

門面模式(Facade)

我有一個專業的Nikon相機,我就喜歡自己手動調光圈、快門,這樣照出來的照片才專業,但MM可不懂這些,教了半天也不會。幸好相機有Facade設計模式,把相機調整到自動檔,只要對準目標按快門就行了,一切由相機自動調整,這樣MM也可以用這個相機給我拍張照片了。
門面模式:外部與一個子系統的通信必須通過一個統一的門面對象進行。門面模式提供一個高層次的接口,使得子系統更易於使用。每一個子系統只有一個門面類,而且此門面類只有一個實例,也就是說它是一個單例模式。但整個系統可以有多個門面類。

享元模式(Flyweight)

每天跟MM發短信,手指都累死了,最2009年買了個新手機,可以把一些常用的句子存在手機裏,要用的時候,直接拿出來,在前面加上MM的名字就可以發送了,再不用一個字一個字敲了。共享的句子就是Flyweight,MM的名字就是提取出來的外部特徵,根據上下文情況使用。
享元模式:FLYWEIGHT在拳擊比賽中指最輕量級。享元模式以共享的方式高效的支持大量的細粒度對象。享元模式能做到共享的關鍵是區分內蘊狀態和外蘊狀態。內蘊狀態存儲在享元內部,不會隨環境的改變而有所不同。外蘊狀態是隨環境的改變而改變的。外蘊狀態不能影響內蘊狀態,它們是相互獨立的。將可以共享的狀態和不可以共享的狀態從常規類中區分開來,將不可以共享的狀態從類裏剔除出去。客戶端不可以直接創建被共享的對象,而應當使用一個工廠對象負責創建被共享的對象。享元模式大幅度的降低內存中對象的數量。

代理模式(Proxy)

跟MM在網上聊天,一開頭總是“hi,你好”,“你從哪兒來呀?”“你多大了?”“身高多少呀?”這些話,真煩人,寫個程序做爲我的Proxy吧,凡是接收到這些話都設置好了自動的回答,接收到其他的話時再通知我回答,怎麼樣,酷吧。
代理模式:代理模式給某一個對象提供一個代理對象,並由代理對象控制對源對象的引用。代理就是一個人或一個機構代表另一個人或者一個機構採取行動。某些情況下,客戶不想或者不能夠直接引用一個對象,代理對象可以在客戶和目標對象直接起到中介的作用。客戶端分辨不出代理主題對象與真實主題對象。代理模式可以並不知道真正的被代理對象,而僅僅持有一個被代理對象的接口,這時候代理對象不能夠創建被代理對象,被代理對象必須有系統的其他角色代爲創建並傳入。

責任鏈模式(Chain of Responsibility)

晚上去上英語課,爲了好開溜坐到了最後一排,哇,前面坐了好幾個漂亮的MM哎,找張紙條,寫上“Hi,可以做我的女朋友嗎?如果不願意請向前傳”,紙條就一個接一個的傳上去了,糟糕,傳到第一排的MM把紙條傳給老師了,聽說是個老處女呀,快跑!
責任鏈模式:在責任鏈模式中,很多對象由每一個對象對其下家的引用而接起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求。客戶並不知道鏈上的哪一個對象最終處理這個請求,系統可以在不影響客戶端的情況下動態的重新組織鏈和分配責任。處理者有兩個選擇:承擔責任或者把責任推給下家。一個請求可以最終不被任何接收端對象所接受。

命令模式(Command)

我有一個MM家裏管得特別嚴,沒法見面,只好藉助於她弟弟在我們倆之間傳送信息,她對我有什麼指示,就寫一張紙條讓她弟弟帶給我。這不,她弟弟又傳送過來一個COMMAND,爲了感謝他,我請他吃了碗雜醬麪,哪知道他說:“我同時給我姐姐三個男朋友送COMMAND,就數你最小氣,才請我吃麪。”
命令模式:命令模式把一個請求或者操作封裝到一個對象中。命令模式把發出命令的責任和執行命令的責任分割開,委派給不同的對象。命令模式允許請求的一方和發送的一方獨立開來,使得請求的一方不必知道接收請求的一方的接口,更不必知道請求是怎麼被接收,以及操作是否執行,何時被執行以及是怎麼被執行的。系統支持命令的撤消。

解析器模式(Interpreter)

俺有一個《泡MM真經》,上面有各種泡MM的攻略,比如說去吃西餐的步驟、去看電影的方法等等,跟MM約會時,只要做一個Interpreter,照着上面的腳本執行就可以了。
解釋器模式:給定一個語言後,解釋器模式可以定義出其文法的一種表示,並同時提供一個解釋器。客戶端可以使用這個解釋器來解釋這個語言中的句子。解釋器模式將描述怎樣在有了一個簡單的文法後,使用模式設計解釋這些語句。在解釋器模式裏面提到的語言是指任何解釋器對象能夠解釋的任何組合。在解釋器模式中需要定義一個代表文法的命令類的等級結構,也就是一系列的組合規則。每一個命令對象都有一個解釋方法,代表對命令對象的解釋。命令對象的等級結構中的對象的任何排列組合都是一個語言。

迭代器模式(Iterator)

我愛上了Mary,不顧一切的向她求婚。
Mary:“想要我跟你結婚,得答應我的條件”
我:“什麼條件我都答應,你說吧”
Mary:“我看上了那個一克拉的鑽石”
我:“我買,我買,還有嗎?”
Mary:“我看上了湖邊的那棟別墅”
我:“我買,我買,還有嗎?”
Mary:“我看上那輛法拉利跑車”
我腦袋嗡的一聲,坐在椅子上,一咬牙:“我買,我買,還有嗎?”
迭代子模式:迭代子模式可以順序訪問一個聚集中的元素而不必暴露聚集的內部表象。多個對象聚在一起形成的總體稱之爲聚集,聚集對象是能夠包容一組對象的容器對象。迭代子模式將迭代邏輯封裝到一個獨立的子對象中,從而與聚集本身隔開。迭代子模式簡化了聚集的界面。每一個聚集對象都可以有一個或一個以上的迭代子對象,每一個迭代子的迭代狀態可以是彼此獨立的。迭代算法可以獨立於聚集角色變化。

中介模式(Mediator)

四個MM打麻將,相互之間誰應該給誰多少錢算不清楚了,幸虧當時我在旁邊,按照各自的籌碼數算錢,賺了錢的從我這裏拿,賠了錢的也付給我,一切就OK啦,俺得到了四個MM的電話。
調停者模式:調停者模式包裝了一系列對象相互作用的方式,使得這些對象不必相互明顯作用。從而使他們可以鬆散偶合。當某些對象之間的作用發生改變時,不會立即影響其他的一些對象之間的作用。保證這些作用可以彼此獨立的變化。調停者模式將多對多的相互作用轉化爲一對多的相互作用。調停者模式將對象的行爲和協作抽象化,把對象在小尺度的行爲上與其他對象的相互作用分開處理。

備忘錄模式(Memento)

同時跟幾個MM聊天時,一定要記清楚剛纔跟MM說了些什麼話,不然MM發現了會不高興的哦,幸虧我有個備忘錄,剛纔與哪個MM說了什麼話我都拷貝一份放到備忘錄裏面保存,這樣可以隨時察看以前的記錄啦。
備忘錄模式:備忘錄對象是一個用來存儲另外一個對象內部狀態的快照的對象。備忘錄模式的用意是在不破壞封裝的條件下,將一個對象的狀態捉住,並外部化,存儲起來,從而可以在將來合適的時候把這個對象還原到存儲起來的狀態。

觀察者模式(Observer)

想知道咱們公司最新MM情報嗎?加入公司的MM情報郵件組就行了,tom負責蒐集情報,他發現的新情報不用一個一個通知我們,直接發佈給郵件組,我們作爲訂閱者(觀察者)就可以及時收到情報啦
觀察者模式:觀察者模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態上發生變化時,會通知所有觀察者對象,使他們能夠自動更新自己。

狀態模式(State)

跟MM交往時,一定要注意她的狀態哦,在不同的狀態時她的行爲會有不同,比如你約她今天晚上去看電影,對你沒興趣的MM就會說 “有事情啦”,對你不討厭但還沒喜歡上的MM就會說“好啊,不過可以帶上我同事麼?”,已經喜歡上你的MM就會說“幾點鐘?看完電影再去泡吧怎麼樣?”,當然你看電影過程中表現良好的話,也可以把MM的狀態從不討厭不喜歡變成喜歡哦。
狀態模式:狀態模式允許一個對象在其內部狀態改變的時候改變行爲。這個對象看上去象是改變了它的類一樣。狀態模式把所研究的對象的行爲包裝在不同的狀態對象裏,每一個狀態對象都屬於一個抽象狀態類的一個子類。狀態模式的意圖是讓一個對象在其內部狀態改變的時候,其行爲也隨之改變。狀態模式需要對每一個系統可能取得的狀態創立一個狀態類的子類。當系統的狀態變化時,系統便改變所選的子類。

策略模式(Strategy)

跟不同類型的MM約會,要用不同的策略,有的請電影比較好,有的則去吃小吃效果不錯,有的去海邊浪漫最合適,但目的都是爲了得到MM的芳心,我的追MM錦囊中有好多Strategy哦。
策略模式:策略模式針對一組算法,將每一個算法封裝到具有共同接口的獨立的類中,從而使得它們可以相互替換。策略模式使得算法可以在不影響到客戶端的情況下發生變化。策略模式把行爲和環境分開。環境類負責維持和查詢行爲類,各種算法在具體的策略類中提供。由於算法和環境獨立開來,算法的增減,修改都不會影響到環境和客戶端。

模版模式(Template)

看過《如何說服女生上牀》這部經典文章嗎?女生從認識到上牀的不變的步驟分爲巧遇、打破僵局、展開追求、接吻、前戲、動手、愛撫、進去八大步驟(Template method),但每個步驟針對不同的情況,都有不一樣的做法,這就要看你隨機應變啦(具體實現);
模板方法模式:模板方法模式準備一個抽象類,將部分邏輯以具體方法以及具體構造子的形式實現,然後聲明一些抽象方法來迫使子類實現剩餘的邏輯。不同的子類可以以不同的方式實現這些抽象方法,從而對剩餘的邏輯有不同的實現。先制定一個頂級邏輯框架,而將邏輯的細節留給具體的子類去實現。

訪問者模式(Visitor)

情人節到了,要給每個MM送一束鮮花和一張卡片,可是每個MM送的花都要針對她個人的特點,每張卡片也要根據個人的特點來挑,我一個人哪搞得清楚,還是找花店老闆和禮品店老闆做一下Visitor,讓花店老闆根據MM的特點選一束花,讓禮品店老闆也根據每個人特點選一張卡,這樣就輕鬆多了;
訪問者模式:訪問者模式的目的是封裝一些施加於某種數據結構元素之上的操作。一旦這些操作需要修改的話,接受這個操作的數據結構可以保持不變。訪問者模式適用於數據結構相對未定的系統,它把數據結構和作用於結構上的操作之間的耦合解脫開,使得操作集合可以相對自由的演化。訪問者模式使得增加新的操作變的很容易,就是增加一個新的訪問者類。訪問者模式將有關的行爲集中到一個訪問者對象中,而不是分散到一個個的節點類中。當使用訪問者模式時,要將儘可能多的對象瀏覽邏輯放在訪問者類中,而不是放到它的子類中。訪問者模式可以跨過幾個類的等級結構訪問屬於不同的等級結構的成員類。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章