設計模式精簡圖冊

設計模式精簡圖冊

首發於個人公衆號html

設計模式圖冊java

設計模式分類

建立型模式:

主要用於建立對象,包括正則表達式

  • 工廠方法(Factory Method)
  • 抽象工廠(Abstract Factory)
  • 單例(Singleton)
  • 生成器(Builder)
  • 原型(Prototype)

結構型模式:

用於處理類或者對象的組合,包括算法

  • 適配器(Adapter)
  • 裝飾者(Decorator)
  • 代理(Proxy)
  • 外觀(Facade)
  • 橋接(Bridge Pattern)
  • 組合(Composite)
  • 輕量(Flyweigh)

行爲型模式:

用於描述類與對象怎樣的交互和分配職責,包括編程

  • 策略(Strategy)
  • 觀察者(Observer)
  • 命令(Command)
  • 模板方法(Template Method)
  • 迭代器(Iterator)
  • 狀態(State)
  • 責任鏈(Chain)
  • 解釋器(Interpreter)
  • 中介者(Mediator)
  • 備忘錄(Memo)
  • 訪問者(Visitor)

設計原則

單一職責原則(Single responsibility principle)

  • 核心 不要存在多於一個致使類變動的緣由。通俗的說,即一個類只負責一項職責。
  • 問題產生 類T負責兩個不一樣的職責:職責P1,職責P2。當因爲職責P1需求發生改變而須要修改類T時,有可能會致使本來運行正常的職責P2功能發生故障。
  • 解決方案 遵循單一職責原則。分別創建兩個類T一、T2,使T1完成職責P1功能,T2完成職責P2功能。這樣,當修改類T1時,不會使職責P2發生故障風險;同理,當修改T2時,也不會使職責P1發生故障風險。

可是因爲職責擴散會致使在實際中每每會有悖於單一職責設計模式

里氏代換原則(Liskov Substitution Principle LSP)

  • 核心 全部引用基類的地方必須能透明地使用其子類的對象。
  • 問題產生 有一功能P1,由類A完成。現須要將功能P1進行擴展,擴展後的功能爲P,其中P由原有功能P1與新功能P2組成。新功能P由類A的子類B來完成,則子類B在完成新功能P2的同時,有可能會致使原有功能P1發生故障。
  • 解決方案 當使用繼承時,遵循里氏替換原則。類B繼承類A時,除添加新的方法完成新增功能P2外,儘可能不要重寫父類A的方法,也儘可能不要重載父類A的方法。

繼承包含這樣一層含義:父類中凡是已經實現好的方法(相對於抽象方法而言),其實是在設定一系列的規範和契約,雖然它不強制要求全部的子類必須聽從這些契約,可是若是子類對這些非抽象方法任意修改,就會對整個繼承體系形成破壞。而里氏替換原則就是表達了這一層含義。安全

繼承做爲面向對象三大特性之一,在給程序設計帶來巨大便利的同時,也帶來了弊端。好比使用繼承會給程序帶來侵入性,程序的可移植性下降,增長了對象間的耦合性,若是一個類被其餘的類所繼承,則當這個類須要修改時,必須考慮到全部的子類,而且父類修改後,全部涉及到子類的功能都有可能會產生故障。數據結構

接口隔離原則(Interface Segregation Principle)

  • 核心 不該該依賴它不須要的接口;一個類對另外一個類的依賴應該創建在最小的接口上
  • 問題產生 類A經過接口I依賴類B,類C經過接口I依賴類D,若是接口I對於類A和類B來講不是最小接口,則類B和類D必須去實現他們不須要的方法。
  • 解決方案 將臃腫的接口I拆分爲獨立的幾個接口,類A和類C分別與他們須要的接口創建依賴關係。也就是採用接口隔離原則。

接口隔離原則跟以前的單一職責原則很類似,其實否則。其一,單一職責原則原注重的是職責;而接口隔離原則注重對接口依賴的隔離。其二,單一職責原則主要是約束類,其次纔是接口和方法,它針對的是程序中的實現和細節;而接口隔離原則主要約束接口接口,主要針對抽象,針對程序總體框架的構建。多線程

採用接口隔離原則對接口進行約束時,要注意如下幾點:架構

  • 接口儘可能小,可是要有限度。對接口進行細化能夠提升程序設計靈活性是不掙的事實,可是若是太小,則會形成接口數量過多,使設計複雜化。因此必定要適度。
  • 爲依賴接口的類定製服務,只暴露給調用的類它須要的方法,它不須要的方法則隱藏起來。只有專一地爲一個模塊提供定製服務,才能創建最小的依賴關係。
  • 提升內聚,減小對外交互。使接口用最少的方法去完成最多的事情。

運用接口隔離原則,必定要適度,接口設計的過大或太小都很差。設計接口的時候,只有多花些時間去思考和籌劃,才能準確地實踐這一原則。

迪米特原則(Law of Demeter/Least Knowledge Principle )

  • 核心 迪米特法則又叫最少知道原則,一個對象應該對其餘對象保持最少的瞭解。
  • 問題產生 類與類之間的關係越密切,耦合度越大,當一個類發生改變時,對另外一個類的影響也越大。
  • 解決方案 儘可能下降類與類之間的耦合。

通俗的來說,就是一個類對本身依賴的類知道的越少越好。也就是說,對於被依賴的類來講,不管邏輯多麼複雜,都儘可能地的將邏輯封裝在類的內部,對外除了提供的public方法,不對外泄漏任何信息, 迪米特法則還有一個更簡單的定義:只與直接的朋友通訊。首先來解釋一下什麼是直接的朋友:每一個對象都會與其餘對象有耦合關係,只要兩個對象之間有耦合關係,咱們就說這兩個對象之間是朋友關係。耦合的方式不少,依賴、關聯、組合、聚合等。其中,咱們稱出現成員變量、方法參數、方法返回值中的類爲直接的朋友,而出如今局部變量中的類則不是直接的朋友。也就是說,陌生的類最好不要做爲局部變量的形式出如今類的內部。

依賴倒置原則(Dependence Inversion Principle)

  • 核心 高層模塊不該該依賴低層模塊,兩者都應該依賴其抽象;抽象不該該依賴細節;細節應該依賴抽象。
  • 問題產生 類A直接依賴類B,假如要將類A改成依賴類C,則必須經過修改類A的代碼來達成。這種場景下,類A通常是高層模塊,負責複雜的業務邏輯;類B和類C是低層模塊,負責基本的原子操做;假如修改類A,會給程序帶來沒必要要的風險。
  • 解決方案 將類A修改成依賴接口I,類B和類C各自實現接口I,類A經過接口I間接與類B或者類C發生聯繫,則會大大下降修改類A的概率。

依賴倒置原則基於這樣一個事實:相對於細節的多變性,抽象的東西要穩定的多。以抽象爲基礎搭建起來的架構比以細節爲基礎搭建起來的架構要穩定的多。在java中,抽象指的是接口或者抽象類,細節就是具體的實現類,使用接口或者抽象類的目的是制定好規範和契約,而不去涉及任何具體的操做,把展示細節的任務交給他們的實現類去完成。

依賴倒置原則的核心思想是面向接口編程,

開閉原則(Open Close Principle)

  • 核心 一個軟件實體如類、模塊和函數應該對擴展開放,對修改關閉。
  • 問題產生 在軟件的生命週期內,由於變化、升級和維護等緣由須要對軟件原有代碼進行修改時,可能會給舊代碼中引入錯誤,也可能會使咱們不得不對整個功能進行重構,而且須要原有代碼通過從新測試。
  • 解決方案 當軟件須要變化時,儘可能經過擴展軟件實體的行爲來實現變化,而不是經過修改已有的代碼來實現變化。

開閉原則無非就是想表達這樣一層意思:用抽象構建框架,用實現擴展細節。由於抽象靈活性好,適應性廣,只要抽象的合理,能夠基本保持軟件架構的穩定。而軟件中易變的細節,咱們用從抽象派生的實現類來進行擴展,當軟件須要發生變化時,咱們只須要根據需求從新派生一個實現類來擴展就能夠了。固然前提是咱們的抽象要合理,要對需求的變動有前瞻性和預見性才行。

幾個原則的關聯性

用抽象構建框架,用實現擴展細節的注意事項而已:

  • 單一職責原則告訴咱們實現類要職責單一;
  • 里氏替換原則告訴咱們不要破壞繼承體系;
  • 依賴倒置原則告訴咱們要面向接口編程;
  • 接口隔離原則告訴咱們在設計接口的時候要精簡單一;
  • 迪米特法則告訴咱們要下降耦合。 而開閉原則是總綱,他告訴咱們要對擴展開放,對修改關閉。

建立型設計模式(建立對象)

工廠方法(Factory Method Pattern)

名稱
Factory Method
結構
動機
定義一個用於建立對象的接口,讓子類決定實例化哪個類。Factory Method 使一個類的實例化延遲到其子類。
適用性
  • 當一個類不知道它所必須建立的對象的類的時候。
  • 當一個類但願由它的子類來指定它所建立的對象的時候。
  • 當類將建立對象的職責委託給多個幫助子類中的某一個,而且你但願將哪個幫助子類是代理者這一信息局部化的時候。
優勢
  • 在工廠方法中,用戶只須要知道所要產品的具體工廠,無須關係具體的建立過程,甚至不須要具體產品類的類名。
  • 在系統增長新的產品時,咱們只須要添加一個具體產品類和對應的實現工廠,無需對原工廠進行任何修改,很好地符合了「開閉原則」。
缺點
  • 每次增長一個產品時,都須要增長一個具體類和對象實現工廠,是的系統中類的個數成倍增長,在必定程度上增長了系統的複雜度,同時也增長了系統具體類的依賴。這並非什麼好事。
小結
  • 簡單工廠模式的要點就在於當你須要什麼,只須要傳入一個正確的參數,就能夠獲取你所須要的對象,而無須知道其建立細節。
  • 簡單工廠模式最大的優勢在於實現對象的建立和對象的使用分離,可是若是產品過多時,會致使工廠代碼很是複雜。

抽象工廠(Abstract Factory Pattern)

名稱
Abstract Factory
結構
動機
提供一個建立一系列相關或相互依賴對象的接口,而無需指定它們具體的類。
適用性
  • 一個系統要獨立於它的產品的建立、組合和表示時。
  • 一個系統要由多個產品系列中的一個來配置時。
  • 當你要強調一系列相關的產品對象的設計以便進行聯合使用時。
  • 當你提供一個產品類庫,而只想顯示它們的接口而不是實現時。
優勢
  • 抽象工廠隔離了具體類的生成,是的客戶端不須要知道什麼被建立。全部的具體工廠都實現了抽象工廠中定義的公共接口,所以只須要改變具體工廠的實例,就能夠在某種程度上改變整個軟件系統的行爲。
  • 當一個產品族中的多個對象被設計成一塊兒工做時,它可以保證客戶端始終只使用同一個產品族中的對象。
缺點
  • 添加新的行爲時比較麻煩。若是須要添加一個新產品族對象時,須要更改接口及其下全部子類,這必然會帶來很大的麻煩。
小結
  • 抽象工廠模式中主要的優勢在於具體類的隔離,是的客戶端不須要知道什麼被建立了。其缺點在於增長新的等級產品結構比較複雜,須要修改接口及其全部子類。

生成器/建造者模式(Builder Pattern)

名稱
Builder
結構
動機
將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。
適用性
  • 當建立複雜對象的算法應該獨立於該對象的組成部分以及它們的裝配方式時。
  • 當構造過程必須容許被構造的對象有不一樣的表示時。
優勢
  • 將複雜產品的建立步驟分解在不一樣的方法中,使得建立過程更加清晰,使得咱們可以更加精確的控制複雜對象的產生過程。
  • 將產品的建立過程與產品自己分離開來,可使用相同的建立過程來獲得不一樣的產品。也就說細節依賴抽象。
  • 每個具體建造者都相對獨立,而與其餘的具體建造者無關,所以能夠很方便地替換具體建造者或增長新的具體建造者,用戶使用不一樣的具體建造者便可獲得不一樣的產品對象。
缺點
  • 建造者模式所建立的產品通常具備較多的共同點,其組成部分類似,若是產品之間的差別性很大,則不適合使用建造者模式,所以其使用範圍受到必定的限制。
  • 若是產品的內部變化複雜,可能會致使須要定義不少具體建造者類來實現這種變化,致使系統變得很龐大。
小結
  • 建造者模式是將一個複雜對象的建立過程給封裝起來,客戶只須要知道能夠利用對象名或者類型就可以獲得一個完整的對象實例,而不須要關心對象的具體建立過程。
  • 建造者模式將對象的建立過程與對象自己隔離開了,使得細節依賴於抽象,符合依賴倒置原則。可使用相同的建立過程來建立不一樣的產品對象。

原型模式(Prototype Pattern)

名稱
Prototype
結構
動機
用原型實例指定建立對象的種類,而且經過拷貝這些原型建立新的對象。
適用性
  • 當要實例化的類是在運行時刻指定時,例如,經過動態裝載;或者
  • 爲了不建立一個與產品類層次平行的工廠類層次時;或者
  • 當一個類的實例只能有幾個不一樣狀態組合中的一種時。創建相應數目的原型並克隆它們可能比每次用合適的狀態手工實例化該類更方便一些。
優勢
  • 若是建立新的對象比較複雜時,能夠利用原型模式簡化對象的建立過程,同時也可以提升效率。
  • 可使用深克隆保持對象的狀態。
  • 原型模式提供了簡化的建立結構。
缺點
  • 在實現深克隆的時候可能須要比較複雜的代碼。
  • 須要爲每個類配備一個克隆方法,並且這個克隆方法須要對類的功能進行通盤考慮,這對全新的類來講不是很難,但對已有的類進行改造時,不必定是件容易的事,必須修改其源代碼,違背了「開閉原則」。
小結
  • 原型模式向客戶隱藏了建立對象的複雜性。客戶只須要知道要建立對象的類型,而後經過請求就能夠得到和該對象如出一轍的新對象,無須知道具體的建立過程。
  • 克隆分爲淺克隆和深克隆兩種。
  • 咱們雖然能夠利用原型模式來得到一個新對象,但有時對象的複製可能會至關的複雜,好比深克隆。

單例模式(Singleton Pattern)

名稱
Singleton
結構
動機
保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。
適用性
  • 當類只能有一個實例並且客戶能夠從一個衆所周知的訪問點訪問它時。
  • 當這個惟一實例應該是經過子類化可擴展的,而且客戶應該無需更改代碼就能使用一個擴展的實例時。
優勢
  • 節約了系統資源。因爲系統中只存在一個實例對象,對與一些須要頻繁建立和銷燬對象的系統而言,單 例模式無疑節約了系統資源和提升了系統的性能。
  • 由於單例類封裝了它的惟一實例,因此它能夠嚴格控制客戶怎樣以及什麼時候訪問它。
缺點
  • 因爲單例模式中沒有抽象層,所以單例類的擴展有很大的困難。
  • 單例類的職責太重,在必定程度上違背了「單一職責原則」。
小結
  • 單例模式中確保程序中一個類最多隻有一個實例。
  • 單例模式的構造器是私有了,並且它必需要提供實例的全局訪問點。
  • 單例模式可能會由於多線程的問題而帶來安全隱患。
public class BetterSingleton {

    private BetterSingleton2() {
    }

    public static BetterSingleton getInstance() {
        return Singleton.BETTER_SINGLETON;
    }

    publicstatic class Singleton{
      private static final  BetterSingleton BETTER_SINGLETON = new BetterSingleton();
    }
}
複製代碼

建立型設計模式小結

模式 場景發散 一句話歸納
工廠方法(Factory Method) new太多如何管理 生產系列產品。
抽象工廠(Abstract Factory) new太多如何管理 一次生產多個不一樣產品。
生成器(Builder) 車手選車 生產有不少組件的產品。
原型(Prototype) 複製不能很難 克隆對象。
單件(Singleton) 如何管理全局信息 全局只有一個。

結構型設計模式(處理類或者對象的組合)

橋接模式(Bridge Pattern)

名稱
Bridge
結構
動機
將抽象部分與它的實現部分分離,使它們均可以獨立地變化。
適用性
  • 若是一個系統須要在構件的抽象化角色和具體化角色之間增長更多的靈活性,避免在兩個層次之間創建靜態的繼承聯繫,經過橋接模式可使它們在抽象層創建一個關聯關係。
  • 對於那些不但願使用繼承或由於多層次繼承致使系統類的個數急劇增長的系統,橋接模式尤其適用
  • 一個類存在兩個獨立變化的維度,且這兩個維度都須要進行擴展。
優勢
  • 分離抽象接口及其實現部分。提升了比繼承更好的解決方案。
  • 橋接模式提升了系統的可擴充性,在兩個變化維度中任意擴展一個維度,都不須要修改原有系統。
  • 實現細節對客戶透明,能夠對用戶隱藏實現細節。
缺點
  • 橋接模式的引入會增長系統的理解與設計難度,因爲聚合關聯關係創建在抽象層,要求開發者針對抽象進行設計與編程。
  • 橋接模式要求正確識別出系統中兩個獨立變化的維度,所以其使用範圍具備必定的侷限性。
小結
  • 橋接模式實現了抽象化與實現化的脫耦。他們兩個互相獨立,不會影響到對方。
  • 對於兩個獨立變化的維度,使用橋接模式再適合不過了。
  • 對於「具體的抽象類」所作的改變,是不會影響到客戶。

輕量模式/享元模式(FlyWeightPattern)

名稱
Flyweight
結構
動機
運用共享技術有效地支持大量細粒度的對象。
適用性
  • 一個應用程序使用了大量的對象。
  • 徹底因爲使用大量的對象,形成很大的存儲開銷。
  • 對象的大多數狀態均可變爲外部狀態。
  • 若是刪除對象的外部狀態,那麼能夠用相對較少的共享對象取代不少組對象。
  • 應用程序不依賴於對象標識。因爲F l y w e i g h t 對象能夠被共享,對於概念上明顯有別的對象,標識測試將返回真值。
優勢
  • 享元模式的優勢在於它可以極大的減小系統中對象的個數。
  • 享元模式因爲使用了外部狀態,外部狀態相對獨立,不會影響到內部狀態,因此享元模式使得享元對象可以在不一樣的環境被共享。
缺點
  • 因爲享元模式須要區分外部狀態和內部狀態,使得應用程序在某種程度上來講更加複雜化了。
  • 爲了使對象能夠共享,享元模式須要將享元對象的狀態外部化,而讀取外部狀態使得運行時間變長。
小結
  • 享元模式能夠極大地減小系統中對象的數量。可是它可能會引發系統的邏輯更加複雜化。
  • 享元模式的核心在於享元工廠,它主要用來確保合理地共享享元對象。
  • 內部狀態爲不變共享部分,存儲於享元享元對象內部,而外部狀態是可變部分,它應當由客戶端來負責。

外觀模式(Facade Pattern)

名稱
Facade
結構
動機
爲子系統中的一組接口提供一個一致的界面,F a c a d e 模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。
適用性
  • 當你要爲一個複雜子系統提供一個簡單接口時。子系統每每由於不斷演化而變得愈來愈複雜。大多數模式使用時都會產生更多更小的類。這使得子系統更具可重用性,也更容易對子系統進行定製,但這也給那些不須要定製子系統的用戶帶來一些使用上的困難。F a c a d e 能夠提供一個簡單的缺省視圖,這一視圖對大多數用戶來講已經足夠,而那些須要更多的可定製性的用戶能夠越過f a c a d e 層。
  • 客戶程序與抽象類的實現部分之間存在着很大的依賴性。引入f a c a d e 將這個子系統與客戶以及其餘的子系統分離,能夠提升子系統的獨立性和可移植性。
  • 當你須要構建一個層次結構的子系統時,使用f a c a d e 模式定義子系統中每層的入口點。若是子系統之間是相互依賴的,你可讓它們僅經過f a c a d e 進行通信,從而簡化了它們之間的依賴關係。
優勢
  • 引入外觀模式,是客戶對子系統的使用變得簡單了,減小了與子系統的關聯對象,實現了子系統與客戶之間的鬆耦合關係。
  • 只是提供了一個訪問子系統的統一入口,並不影響用戶直接使用子系統類
  • 下降了大型軟件系統中的編譯依賴性,並簡化了系統在不一樣平臺之間的移植過程
缺點
  • 不能很好地限制客戶使用子系統類,若是對客戶訪問子系統類作太多的限制則減小了可變性和靈活性
  • 在不引入抽象外觀類的狀況下,增長新的子系統可能須要修改外觀類或客戶端的源代碼,違背了「開閉原則」
小結
  • 外觀模式的主要優勢就在於減小了客戶與子系統之間的關聯對象,使用客戶對子系統的使用變得簡單了,也實現了客戶端與子系統之間的鬆耦合關係。它的缺點就在於違背了「開閉原則」。
  • 若是須要實現一個外觀模式,須要將子系統組合進外觀中,而後將工做委託給子系統執行。

裝飾者模式(Decorator Pattern)

名稱
Decorator
結構
動機
動態地給一個對象添加一些額外的職責。就增長功能來講,D e c o r a t o r 模式相比生成子類更爲靈活。
適用性
  • 在不影響其餘對象的狀況下,以動態、透明的方式給單個對象添加職責。
  • 處理那些能夠撤消的職責。
  • 當不能採用生成子類的方法進行擴充時。一種狀況是,可能有大量獨立的擴展,爲支持每一種組合將產生大量的子類,使得子類數目呈爆炸性增加。另外一種狀況多是由於類定義被隱藏,或類定義不能用於生成子類。
優勢
  • 裝飾者模式能夠提供比繼承更多的靈活性
  • 能夠經過一種動態的方式來擴展一個對象的功能,在運行時選擇不一樣的裝飾器,從而實現不一樣的行爲。
  • 經過使用不一樣的具體裝飾類以及這些裝飾類的排列組合,能夠創造出不少不一樣行爲的組合。可使用多個具體裝飾類來裝飾同一對象,獲得功能更爲強大的對象。
  • 具體構件類與具體裝飾類能夠獨立變化,用戶能夠根據須要增長新的具體構件類和具體裝飾類,在使用時再對其進行組合,原有代碼無須改變,符合「開閉原則」。
缺點
  • 會產生不少的小對象,增長了系統的複雜性
  • 這種比繼承更加靈活機動的特性,也同時意味着裝飾模式比繼承更加易於出錯,排錯也很困難,對於屢次裝飾的對象,調試時尋找錯誤可能須要逐級排查,較爲煩瑣。
小結
  • 裝飾者模式意味着一羣裝飾者類,這些類用來包裝具體組件
  • 裝飾者能夠在被裝飾者的行爲前面或者後面加上本身的行爲,甚至能夠將被裝飾者的行爲整個取代掉,從而達到特定的目的。
  • 能夠用多個裝飾者包裝一個組件。
  • 裝飾者通常對於組件的客戶是透明的,除非客戶程序依賴於組件的具體類型。
  • 裝飾者會致使設計中出現許多的小對象,若是過分的使用,會讓系統變得更加複雜。
  • 裝飾者和被裝飾者對象有相同的超類型。

組合模式(Composite Pattern)

名稱
Composite
結構
動機
將對象組合成樹形結構以表示?部分-總體?的層次結構。C o m p o s i t e 使得用戶對單個對象和組合對象的使用具備一致性。
適用性
  • 你想表示對象的部分-總體層次結構。
  • 你但願用戶忽略組合對象與單個對象的不一樣,用戶將統一地使用組合結構中的全部對象。
優勢
  • 能夠清楚地定義分層次的複雜對象,表示對象的所有或部分層次,使得增長新構件也更容易。
  • 客戶端調用簡單,客戶端能夠一致的使用組合結構或其中單個對象。
  • 定義了包含葉子對象和容器對象的類層次結構,葉子對象能夠被組合成更復雜的容器對象,而這個容器對象又能夠被組合,這樣不斷遞歸下去,能夠造成複雜的樹形結構。
  • 更容易在組合體內加入對象構件,客戶端沒必要由於加入了新的對象構件而更改原有代碼。
缺點
  • 使設計變得更加抽象,對象的業務規則若是很複雜,則實現組合模式具備很大挑戰性,並且不是全部的方法都與葉子對象子類都有關聯,會有冗餘代碼
小結
  • 組合模式用於將多個對象組合成樹形結構以表示「總體-部分」的結構層次。組合模式對單個對象(葉子對象)和組合對象(容器對象)的使用具備一致性。
  • 組合對象的關鍵在於它定義了一個抽象構建類,它既可表示葉子對象,也可表示容器對象,客戶僅僅須要針對這個抽象構建進行編程,無須知道他是葉子對象仍是容器對象,都是一致對待。
  • 組合模式雖然可以很是好地處理層次結構,也使得客戶端程序變得簡單,可是它也使得設計變得更加抽象,並且也很難對容器中的構件類型進行限制,這會致使在增長新的構件時會產生一些問題。

代理模式(Proxy Pattern)

名稱
Proxy
結構
動機
爲其餘對象提供一種代理以控制對這個對象的訪問。
適用性
  • 不但願某些類被直接訪問。
  • 訪問以前但願先進行一些預處理。
  • 但願對被訪問的對象進行內存、權限等方面的控制。 模式。
優勢
  • 代理模式可以協調調用者和被調用者,在必定程度上下降了系統的耦合度。
  • 代理對象能夠在客戶端和目標對象之間起到中介的做用,這樣起到了的做用和保護了目標對象的
缺點
  • 因爲在客戶端和真實主題之間增長了代理對象,所以有些類型的代理模式可能會形成請求的處理速度變慢。
  • 實現代理模式須要額外的工做,有些代理模式的實現很是複雜。
小結
  • 代理模式是經過使用引用代理對象來訪問真實對象,在這裏代理對象充當用於鏈接客戶端和真實對象的中介者。
  • 代理模式主要用於遠程代理、虛擬代理和保護代理。其中保護代理能夠進行訪問權限控制。

適配器模式(Adapter Pattern)

名稱
Adapter
結構
<div data-type="image" data-display="block" data-align="center" data-src="http://www.uml.org.cn/chanpin/intro/WebHelp/Adapter_Class.gif" data-width="543">
          <img src="http://www.uml.org.cn/chanpin/intro/WebHelp/Adapter_Class.gif" width="543" />
        </div>
      </div>
    </td>
  </tr>
  <tr>
    <td rowspan="1" colSpan="1">
      <div data-type="p">動機</div>
    </td>
    <td rowspan="1" colSpan="1">
      <div data-type="p">將一個類的接口轉換成客戶但願的另一個接口。Adapter 模式使得本來因爲接口不兼容而不能一塊兒工做的那些類能夠一塊兒工做。</div>
    </td>
  </tr>
  <tr>
    <td rowspan="1" colSpan="1">
      <div data-type="p">適用性</div>
    </td>
    <td rowspan="1" colSpan="1">
      <ul data-type="unordered-list">
        <li data-type="list-item" data-list-type="unordered-list">
          <div data-type="p">你想使用一個已經存在的類,而它的接口不符合你的需求。</div>
        </li>
        <li data-type="list-item" data-list-type="unordered-list">
          <div data-type="p">你想建立一個能夠複用的類,該類能夠與其餘不相關的類或不可預見的類(即那些接口可能不必定兼容的類)協同工做。</div>
        </li>
        <li data-type="list-item" data-list-type="unordered-list">
          <div data-type="p">(僅適用於對象Adapter )你想使用一些已經存在的子類,可是不可能對每個都進行子類化以匹配它們的接口。對象適配器能夠適配它的父類接口。</div>
        </li>
      </ul>
    </td>
  </tr>
  <tr height="34px">
    <td rowspan="1" colSpan="1">
      <div data-type="p">優勢</div>
    </td>
    <td rowspan="1" colSpan="1">
      <ul data-type="unordered-list">
        <li data-type="list-item" data-list-type="unordered-list">
          <div data-type="p">將目標類和適配者類解耦,經過使用適配器讓不兼容的接口變成了兼容,讓客戶從實現的接口解耦。</div>
        </li>
        <li data-type="list-item" data-list-type="unordered-list">
          <div data-type="p">增長了類的透明性和複用性,將具體的實現封裝在適配者類中,對於客戶端類來講是透明的,並且提升了適配者的複用性。</div>
        </li>
        <li data-type="list-item" data-list-type="unordered-list">
          <div data-type="p">靈活性和擴展性都很是好在不修改原有代碼的基礎上增長新的適配器類,符合「開閉原則」。</div>
        </li>
      </ul>
    </td>
  </tr>
  <tr height="34px">
    <td rowspan="1" colSpan="1">
      <div data-type="p">缺點</div>
    </td>
    <td rowspan="1" colSpan="1">
      <ul data-type="unordered-list">
        <li data-type="list-item" data-list-type="unordered-list">
          <div data-type="p">過多地使用適配器,會讓系統很是零亂,不易總體進行把握。好比,明明看到調用的是 A 接口,其實內部被適配成了 B 接口的實現,一個系統若是太多出現這種狀況,無異於一場災難。</div>
        </li>
        <li data-type="list-item" data-list-type="unordered-list">
          <div data-type="p">所以若是不是頗有必要,能夠不使用適配器,而是直接對系統進行重構。</div>
        </li>
      </ul>
    </td>
  </tr>
  <tr height="34px">
    <td rowspan="1" colSpan="1">
      <div data-type="p">小結</div>
    </td>
    <td rowspan="1" colSpan="1">
      <ul data-type="unordered-list">
        <li data-type="list-item" data-list-type="unordered-list">
          <div data-type="p">當咱們須要使用的一個現有的類,可是他的接口並不符合咱們的需求時,咱們可使用適配器模式。</div>
        </li>
        <li data-type="list-item" data-list-type="unordered-list">
          <div data-type="p">適配器模式分爲類適配器和對象適配器,其中類適配器須要用到多重繼承。</div>
        </li>
      </ul>
    </td>
  </tr>
</tbody>
複製代碼

結構型設計模式小結

模式 場景發散 一句話說明
橋(Bridge) 麻煩的日誌記錄 將「抽象」和「實現」自由搭配。
輕量(Flyweight) 森林裏的樹太多了 輕鬆地處理「大量」對象。
外觀(Façade) 超級手機 同時提供簡單接口和複雜接口。
裝飾者(Decorator) 星巴克的飲料計較系統 不改變接口但要加強功能。
組合(Composite) 超酷的繪圖軟件 無論你是老子仍是兒子,都同樣處理。
代理(Proxy) 找中介租房 代理要控制你的訪問,同時讓你的訪問更舒服 。
適配器(Adapter) 老掉牙系統的重生 不改變功能但要改變接口

行爲型設計模式(類與對象怎樣的交互和分配職責)

觀察者模式(Observer Pattern)

名稱
Observer
結構
動機
定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時, 全部依賴於它的對象都獲得通知並被自動更新。
適用性
  • 當一個抽象模型有兩個方面, 其中一個方面依賴於另外一方面。將這兩者封裝在獨立的對象中以使它們能夠各自獨立地改變和複用。
  • 當對一個對象的改變須要同時改變其它對象, 而不知道具體有多少對象有待改變。
  • 當一個對象必須通知其它對象,而它又不能假定其它對象是誰。換言之, 你不但願這些對象是緊密耦合的。
優勢
  • 當兩個對象之間送耦合,他們依然能夠交互,可是不太清楚彼此的細節。觀察者模式提供了一種對象設計,讓主題和觀察者之間送耦合。主題所知道只是一個具體的觀察者列表,每個具體觀察者都符合一個抽象觀察者的接口。主題並不認識任何一個具體的觀察者,它只知道他們都有一個共同的接口。
  • 觀察者模式支持「廣播通訊」。主題會向全部的觀察者發出通知。
  • 觀察者模式符合「開閉原則」的要求。
缺點
  • 若是一個被觀察者對象有不少的直接和間接的觀察者的話,將全部的觀察者都通知到會花費不少時間。
  • 若是在觀察者和觀察目標之間有循環依賴的話,觀察目標會觸發它們之間進 行循環調用,可能致使系統崩潰。
  • 觀察者模式沒有相應的機制讓觀察者知道所觀察的目標對象是怎麼發生變化的,而僅僅只是知道觀察目標發生了變化。
小結
  • 觀察者模式定義了對象之間的一對多關係。多個觀察者監聽同一個被觀察者,當該被觀察者的狀態發生改變時,會通知全部的觀察者。
  • 觀察者模式中包含四個角色。主題,它指被觀察的對象。具體主題是主題子類,一般它包含有常常發生改變的數據,當它的狀態發生改變時,向它的各個觀察者發出通知;觀察者,將對觀察主題的改變作出反應;具體觀察者中維護一個指向具體目標對象的引用,它存儲具體觀察者的有關狀態,這些狀態須要和具體目標的狀態保持一致。

策略模式(Strategy Pattern)

名稱
Strategy
結構
動機
定義一系列的算法,把它們一個個封裝起來, 而且使它們可相互替換。本模式使得算法可獨立於使用它的客戶而變化。
適用性
  • 許多相關的類僅僅是行爲有異。策略模式提供了一種用多個行爲中的一個行爲來配置一個類的方法。
  • 須要使用一個算法的不一樣變體。
  • 算法使用客戶不該該知道的數據。可以使用策略模式以免暴露覆雜的、與算法相關的數據結構。
  • 一個類定義了多種行爲, 而且這些行爲在這個類的操做中以多個條件語句的形式出現。將相關的條件分支移入它們各自的S t r a t e g y 類中以代替這些條件語句。
優勢
  • 策略模式提供了對「開閉原則」的完美支持,用戶能夠在不修改原有系統的基礎上選擇算法或行爲,也能夠靈活地增長新的算法或行爲。
  • 策略模式提供了能夠替換繼承關係的辦法。
  • 使用策略模式能夠避免使用多重條件轉移語句。
缺點
  • 客戶端必須知道全部的策略類,並自行決定使用哪個策略類。
  • 策略模式將形成產生不少策略類,
小結
  • 若是在一個系統裏面有許多類,它們之間的區別僅在於它們的行爲,那麼使用策略模式能夠動態地讓一個對象在許多行爲中選擇一種行爲。
  • 一個系統須要動態地在幾種算法中選擇一種。
  • 若是一個對象有不少的行爲,若是不用恰當的模式,這些行爲就只好使用多重的條件選擇語句來實現。

迭代器模式(Iterator Pattern)

名稱
Iterator
結構
動機
提供一種方法順序訪問一個聚合對象中各個元素, 而又不需暴露該對象的內部表示。
適用性
  • 訪問一個聚合對象的內容而無需暴露它的內部表示。
  • 支持對聚合對象的多種遍歷。
  • 爲遍歷不一樣的聚合結構提供一個統一的接口(即, 支持多態迭代)。
優勢
  • 它支持以不一樣的方式遍歷一個聚合對象。
  • 迭代器簡化了聚合類。
  • 在同一個聚合上能夠有多個遍歷。
  • 在迭代器模式中,增長新的聚合類和迭代器類都很方便,無須修改原有代碼。
缺點
  • 因爲迭代器模式將存儲數據和遍歷數據的職責分離,增長新的聚合類須要對應增長新的迭代器類,類的個數成對增長,這在必定程度上增長了系統的複雜性。
小結
  • 將遍歷聚合對象中數據的行爲提取出來,封裝到一個迭代器中,經過專門的迭代器來遍歷聚合對象的內部數據,這就是迭代器模式的本質。迭代器模式是「單一職責原則」的完美體現。
  • 當使用迭代器的時候,咱們依賴聚合提供遍歷。
  • 迭代器提供了一個通用的接口,讓咱們遍歷聚合的項,放咱們編碼使用聚合項時,就可使用多態機制。

命令模式(Command Pattern)

名稱
Command
結構
動機
將一個請求封裝爲一個對象,從而使你可用不一樣的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可撤消的操做。
適用性
  • 抽象出待執行的動做以參數化某對象,你可用過程語言中的回調(c a l l b a c k )函數表達這種參數化機制。所謂回調函數是指函數先在某處註冊,而它將在稍後某個須要的時候被調用。C o m m a n d 模式是回調機制的一個面向對象的替代品。
  • 在不一樣的時刻指定、排列和執行請求。一個C o m m a n d 對象能夠有一個與初始請求無關的生存期。若是一個請求的接收者可用一種與地址空間無關的方式表達,那麼就可將負責該請求的命令對象傳送給另外一個不一樣的進程並在那兒實現該請求。
  • 支持取消操做。C o m m a n d 的E x c u t e 操做可在實施操做前將狀態存儲起來,在取消操做時這個狀態用來消除該操做的影響。C o m m a n d 接口必須添加一個U n e x e c u t e 操做,該操做取消上一次E x e c u t e 調用的效果。執行的命令被存儲在一個歷史列表中。可經過向後和向前遍歷這一列表並分別調用U n e x e c u t e 和E x e c u t e 來實現重數不限的取消和重作。
  • 支持修改日誌,這樣當系統崩潰時,這些修改能夠被重作一遍。在C o m m a n d 接口中添加裝載操做和存儲操做,能夠用來保持變更的一個一致的修改日誌。從崩潰中恢復的過程包括從磁盤中從新讀入記錄下來的命令並用E x e c u t e 操做從新執行它們。
  • 用構建在原語操做上的高層操做構造一個系統。這樣一種結構在支持事務( t r a n s a c t i o n )的信息系統中很常見。一個事務封裝了對數據的一組變更。C o m m a n d 模式提供了對事務進行建模的方法。C o m m a n d 有一個公共的接口,使得你能夠用同一種方式調用全部的事務。同時使用該模式也易於添加新事務以擴展系統。
優勢
  • 下降了系統耦合度
  • 新的命令能夠很容易添加到系統中去。
缺點
  • 使用命令模式可能會致使某些系統有過多的具體命令類。
小結
  • 命令模式的本質就是將命令對象進行封裝打包,將發出命令的責任和執行命令的責任進行割開。
  • 命令模式中發送者只須要知道如何發送請求命令,無須關心命令執行具體過程。
  • 在發送者和接收者二者間是經過命令對象進行溝通的。請求命令自己就當作一個對象在二者間進行傳遞,它封裝了接收者和一組動做。
  • 命令模式支持撤銷。
  • 命令模式隊列請求和日誌請求。

訪問者模式(Visitor Pattern)

名稱
Visitor
結構
動機
表示一個做用於某對象結構中的各元素的操做。它使你能夠在不改變各元素的類的前提下定義做用於這些元素的新操做。
適用性
  • 一個對象結構包含不少類對象,它們有不一樣的接口,而你想對這些對象實施一些依賴於其具體類的操做。
  • 須要對一個對象結構中的對象進行不少不一樣的而且不相關的操做,而你想避免讓這些操做?污染?這些對象的類。Vi s i t o r 使得你能夠將相關的操做集中起來定義在一個類中。當該對象結構被不少應用共享時,用Vi s i t o r 模式讓每一個應用僅包含須要用到的操做。
  • 定義對象結構的類不多改變,但常常須要在此結構上定義新的操做。改變對象結構類須要重定義對全部訪問者的接口,這可能須要很大的代價。若是對象結構類常常改變,那麼可能仍是在這些類中定義這些操做較好。
優勢
  • 使得新增新的訪問操做變得更加簡單。
  • 可以使得用戶在不修改現有類的層次結構下,定義該類層次結構的操做。
  • 將有關元素對象的訪問行爲集中到一個訪問者對象中,而不是分散搞一個個的元素類中。
缺點
  • 增長新的元素類很困難。在訪問者模式中,每增長一個新的元素類都意味着要在抽象訪問者角色中增長一個新的抽象操做,並在每個具體訪問者類中增長相應的具體操做,違背了「開閉原則」的要求。
  • 破壞封裝。當採用訪問者模式的時候,就會打破組合類的封裝。
小結
  • 1.SomeClass 的 Accept()方法就是訪問原來類的小口, Accept()方法只有一句代碼,就是: visitor.NewMethod(this) ,這是訪問者模式的精妙之處。 2.SomeClass 的新功能經過實現 IVisitor 接口的類來實現。
  • 訪問者模式封裝了對象結構元素之上的操做,使得新增元素的操做變得很是簡單。因此它比較適用於那麼對象結構不多變化的類。
  • 訪問者模式中對象結構存儲了不一樣類型的元素對象,以供不一樣訪問者訪問。

解釋器模式(Interpreter Pattern)

名稱
Interpreter
結構
動機
給定一個語言,定義它的文法的一種表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。
適用性
  • 當有一個語言須要解釋執行, 而且你可將該語言中的句子表示爲一個抽象語法樹時,可以使用解釋器模式。而當存在如下狀況時該模式效果最好:
  • 該文法簡單對於複雜的文法, 文法的類層次變得龐大而沒法管理。此時語法分析程序生成器這樣的工具是更好的選擇。它們無需構建抽象語法樹便可解釋表達式, 這樣能夠節省空間並且還可能節省時間。
  • 效率不是一個關鍵問題最高效的解釋器一般不是經過直接解釋語法分析樹實現的, 而是首先將它們轉換成另外一種形式。例如,正則表達式一般被轉換成狀態機。但即便在這種狀況下, 轉換器仍可用解釋器模式實現, 該模式還是有用的。
優勢
  • 可擴展性比較好,靈活。
  • 增長了新的解釋表達式的方式。
  • 易於實現文法。
缺點
  • 執行效率比較低,可利用場景比較少。
  • 對於複雜的文法比較難維護。
小結
  • 在解釋器模式中因爲語法是由不少類表示的,因此可擴展性強。
  • 雖然解釋器的可擴展性強,可是若是語法規則的數目太大的時候,該模式可能就會變得異常複雜。因此解釋器模式適用於文法較爲簡單的。
  • 解釋器模式能夠處理腳本語言和編程語言。經常使用於解決某一特定類型的問題頻繁發生狀況。

中介者模式(Mediator Pattern)

名稱
Mediator
結構
動機
用一箇中介對象來封裝一系列的對象交互。中介者使各對象不須要顯式地相互引用,從而使其耦合鬆散,並且能夠獨立地改變它們之間的交互。
適用性
  • 一組對象以定義良好可是複雜的方式進行通訊。產生的相互依賴關係結構混亂且難以理解。
  • 一個對象引用其餘不少對象而且直接與這些對象通訊,致使難以複用該對象。
  • 想定製一個分佈在多個類中的行爲,而又不想生成太多的子類。
優勢
  • 簡化了對象之間的關係,將系統的各個對象之間的相互關係進行封裝,將各個同事類解耦,使系統成爲鬆耦合系統。
  • 減小了子類的生成。
  • 能夠減小各同事類的設計與實現。
缺點
  • 因爲中介者對象封裝了系統中對象之間的相互關係,致使其變得很是複雜,使得系統維護比較困難。
小結
  • 每一個控件不須要直接和別的控件打交道,只須要知道中介者就能夠了。
  • 每一個控件都須要保持保持中介者的引用,而中介者不必定須要保持每一個控件的引用
  • Mediator 的代碼可能很複雜。

備忘錄模式(Memento Pattern)

名稱
Mediator
結構
動機
用一箇中介對象來封裝一系列的對象交互。中介者使各對象不須要顯式地相互引用,從而使其耦合鬆散,並且能夠獨立地改變它們之間的交互。
適用性
  • 一組對象以定義良好可是複雜的方式進行通訊。產生的相互依賴關係結構混亂且難以理解。
  • 一個對象引用其餘不少對象而且直接與這些對象通訊,致使難以複用該對象。
  • 想定製一個分佈在多個類中的行爲,而又不想生成太多的子類。
優勢
  • 給用戶提供了一種能夠恢復狀態的機制。能夠是用戶可以比較方便地回到某個歷史的狀態。
  • 實現了信息的封裝。使得用戶不須要關心狀態的保存細節。
缺點
  • 消耗資源。若是類的成員變量過多,勢必會佔用比較大的資源,並且每一次保存都會消耗必定的內存。
小結
  • 到須要保存對象多個狀態,而且能夠恢復到任意狀態,可考慮備忘錄模式。
  • 將對象、對象狀態和狀態的保存辦法分離,設計上會更加靈活。
  • 但對象屬性的備份、恢復、保存等動做,都是可能比較耗時的。
  • 備忘錄模式只是提供了保存對象狀態的一種解決方案框架 ,真正應用時還須要解決這些 問題:1.如何設計 Memento? 2.怎樣保存多個對象? 3.怎樣保存組織成樹結構的多個對象?

模板方法模式(TemplateMethod Pattern)

名稱
Template Method
結構
動機
定義一個操做中的算法的骨架,而將一些步驟延遲到子類中。Te m p l a t e M e t h o d 使得子類能夠不改變一個算法的結構便可重定義該算法的某些特定步驟。
適用性
  • 算法的骨架是不變的,但其中的步驟實現可能有變化,這時可應用模板方法。
優勢
  • 模板方法模式在定義了一組算法,將具體的實現交由子類負責。
  • 模板方法模式是一種代碼複用的基本技術。
  • 模板方法模式致使一種反向的控制結構,經過一個父類調用其子類的操做,經過對子類的擴展增長新的行爲,符合「開閉原則」。
缺點
  • 每個不一樣的實現都須要一個子類來實現,致使類的個數增長,是的系統更加龐大。
小結
  • 模板方法模式定義了算法的步驟,將這些步驟的實現延遲到了子類。
  • 模板方法模式爲咱們提供了一種代碼複用的重要技巧。
  • 模板方法模式的抽象類能夠定義抽象方法、具體方法和鉤子。
  • 爲了防止子類改變算法的實現步驟,咱們能夠將模板方法聲明爲final。

狀態模式(State Pattern)

名稱
State
結構
動機
容許一個對象在其內部狀態改變時改變它的行爲。對象看起來彷佛修改了它的類。
適用性
  • 一個對象的行爲取決於它的狀態, 而且它必須在運行時刻根據狀態改變它的行爲。
  • 一個操做中含有龐大的多分支的條件語句,且這些分支依賴於該對象的狀態。這個狀態一般用一個或多個枚舉常量表示。一般, 有多個操做包含這一相同的條件結構。S t a t e模式將每個條件分支放入一個獨立的類中。這使得你能夠根據對象自身的狀況將對象的狀態做爲一個對象,這一對象能夠不依賴於其餘對象而獨立變化。
優勢
  • 封裝了轉換規則。
  • 枚舉可能的狀態,在枚舉狀態以前須要肯定狀態種類。
  • 將全部與某個狀態有關的行爲放到一個類中,而且能夠方便地增長新的狀態,只須要改變對象狀態便可改變對象的行爲。
  • 容許狀態轉換邏輯與狀態對象合成一體,而不是某一個巨大的條件語句塊。
  • 可讓多個環境對象共享一個狀態對象,從而減小系統中對象的個數。
缺點
  • 狀態模式的使用必然會增長系統類和對象的個數。
  • 狀態模式的結構與實現都較爲複雜,若是使用不當將致使程序結構和代碼的混亂。
  • 狀態模式對「開閉原則」的支持並不太好,對於能夠切換狀態的狀態模式,增長新的狀態類須要修改那些負責狀態轉換的源代碼,不然沒法切換到新增狀態;並且修改某個狀態類的行爲也需修改對應類的源代碼。
小結
  • 狀態模式容許一個對象基於內部狀態而擁有不一樣的行爲。
  • Context會將行爲委託給當前狀態對象。
  • 狀態模式對「開閉原則」支持不是很好。

責任鏈模式(Chain of Responsibility Pattern)

名稱
Chain of Responsibility
結構
動機
使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關係。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理它爲止。
適用性
  • 有多個的對象能夠處理一個請求,哪一個對象處理該請求運行時刻自動肯定。
  • 你想在不明確指定接收者的狀況下,向多個對象中的一個提交一個請求。
  • 可處理一個請求的對象集合應被動態指定。
優勢
  • 下降耦合度。它將請求的發送者和接受者解耦。
  • 簡化了對象。使得對象不須要知道鏈的結構。
  • 加強給對象指派職責的靈活性。經過改變鏈內的成員或者調動它們的次序,容許動態地新增或者刪除責任。
  • 增長新的請求處理類很方便。
缺點
  • 不能保證請求必定被接收。
  • 系統性能將受到必定影響,並且在進行代碼調試時不太方便;可能會形成循環調用
  • 可能不容易觀察運行時的特徵,有礙於除錯。
小結
  • 職責鏈模式將請求的發送者和接受者解耦了。客戶端不須要知道請求處理者的明確信息,甚至不須要知道鏈的結構,它只須要將請求進行發送便可。
  • 職責鏈模式可以很是方便的動態增長新職責或者刪除職責。
  • 客戶端發送的請求可能會得不處處理。
  • 處理者不須要知道鏈的結構,只須要明白他的後續者是誰就能夠了。這樣就簡化了系統中的對象。

行爲型設計模式小結

模式 場景發散 一句話說明
觀察者(Observer) 同步更新的問題 一呼百應。
策略(Strategy) 設計你的戰士 分離算法。
迭代器(Iterator) 集合訪問的煩惱 以一致的方式訪問集合, 「鬆綁 」遍歷算法代碼。
命令(Command) 神奇的Do與Undo 分離功能調用者與功能實現者。
訪問者(Visitor) 增長新方法的煩惱 不改變對象結構增長新方法。
解釋器(Interpreter) 超級表達解釋引擎 語法解釋。
中介者(Mediator) 麻煩的多角關係 處理多對多關係。
備忘錄(Memento) 假如一切能夠重來 保存對象的多個狀態並可任意恢復。
模板方法(Template Method) 萬能的排序器 定義好框架算法 ,某些步驟可本身定義 。
狀態(State) 是攻擊仍是逃走 方便地處理不一樣狀態不一樣行爲,以及狀態之間的轉換。
責任鏈(Chain) 郵件自動處理系統 用不一樣的規則去處理請求。

模式比較

參考

公衆號小.jpg
相關文章
相關標籤/搜索