1. 程式人生 > >JAVA 23種設計模式簡介

JAVA 23種設計模式簡介

  設計模式(Design Patterns) ——可複用面向物件軟體的基礎

  設計模式(Design pattern)是一套被反覆使用、多數人知曉的、經過分類編目的、程式碼設計經驗的總結。使用設計模式是為了可重用程式碼、讓程式碼更容易被他人理解、保證程式碼可靠性。

設計模式的分類

  建立型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。

  結構型模式,共七種:介面卡模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。其中物件的介面卡模式是各種模式的起源,如下圖:
  這裡寫圖片描述

  行為型模式,共十一種:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、直譯器模式。
  行為模式分四類,第一類:通過父類與子類的關係進行實現。第二類:兩個類之間。第三類:類的狀態。第四類:通過中間類。
  這裡寫圖片描述

  其實還有兩類:併發型模式和執行緒池模式。用一個圖片來整體描述一下:
  這裡寫圖片描述

  Abstract Factory(抽象工廠模式):提供一個建立一系列相關或相互依賴物件的介面,而無需指定它們具體的類。

  Adapter(介面卡模式):將一個類的介面轉換成客戶希望的另外一個介面。A d a p t e r模式使得原本由於介面不相容而不能一起工作的那些類可以一起工作。

  Bridge(橋接模式):將抽象部分與它的實現部分分離,使它們都可以獨立地變化。

  Builder(建造者模式):將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。

  Chain of Responsibility(職責鏈模式):為解除請求的傳送者和接收者之間耦合,而使多個物件都有機會處理這個請求。將這些物件連成一條鏈,並沿著這條鏈傳遞該請求,直到有一個物件處理它。

  Command(命令模式):將一個請求封裝為一個物件,從而使你可用不同的請求對客戶進行引數化;對請求排隊或記錄請求日誌,以及支援可取消的操作。

  Composite(組合模式):將物件組合成樹形結構以表示“部分-整體”的層次結構。它使得客戶對單個物件和複合物件的使用具有一致性。

  Decorator(裝飾模式):動態地給一個物件新增一些額外的職責。就擴充套件功能而言, 它比生成子類方式更為靈活。

  Facade(外觀模式):為子系統中的一組介面提供一個一致的介面, F a c a d e模式定義了一個高層介面,這個介面使得這一子系統更加容易使用。

  Factory Method(工廠模式):定義一個用於建立物件的介面,讓子類決定將哪一個類例項化。Factory Method使一個類的例項化延遲到其子類。

  Flyweight(享元模式):運用共享技術有效地支援大量細粒度的物件。

  Interpreter(解析器模式):給定一個語言, 定義它的文法的一種表示,並定義一個直譯器, 該直譯器使用該表示來解釋語言中的句子。

Iterator(迭代器模式):提供一種方法順序訪問一個聚合物件中各個元素, 而又不需暴露該物件的內部表示。

  Mediator(中介模式):用一箇中介物件來封裝一系列的物件互動。中介者使各物件不需要顯式地相互引用,從而使其耦合鬆散,而且可以獨立地改變它們之間的互動。

  Memento(備忘錄模式):在不破壞封裝性的前提下,捕獲一個物件的內部狀態,並在該物件之外儲存這個狀態。這樣以後就可將該物件恢復到儲存的狀態。

  Observer(觀察者模式):定義物件間的一種一對多的依賴關係,以便當一個物件的狀態發生改變時,所有依賴於它的物件都得到通知並自動重新整理。

  Prototype(原型模式):用原型例項指定建立物件的種類,並且通過拷貝這個原型來建立新的物件。

  Proxy(代理模式):為其他物件提供一個代理以控制對這個物件的訪問[1]。

  Singleton(單例模式):保證一個類僅有一個例項,並提供一個訪問它的全域性訪問點。 單例模式是最簡單的設計模式之一,但是對於Java的開發者來說,它卻有很多缺陷。在本月的專欄中,David Geary探討了單例模式以及在面對多執行緒(multithreading)、類裝載器(classloaders)和序列化(serialization)時如何處理這些缺陷。[2]

  State(狀態模式):允許一個物件在其內部狀態改變時改變它的行為。物件看起來似乎修改了它所屬的類。

Strategy(策略模式):定義一系列的演算法,把它們一個個封裝起來, 並且使它們可相互替換。本模式使得演算法的變化可獨立於使用它的客戶。

  Template Method(模板方法模式):定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中。Template Method使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。

  Visitor(訪問者模式):表示一個作用於某物件結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用於這些元素的新操作。

模式的意圖和實用性

Factory Method
  意圖 : 定義一個用於建立物件的介面,讓子類決定例項化哪一個類。Factory Method 使一個類的例項化延遲到其子類。

  適用性 : 當一個類不知道它所必須建立的物件的類的時候。

  當一個類希望由它的子類來指定它所建立的物件的時候。

  當類將建立物件的職責委託給多個幫助子類中的某一個,並且你希望將哪一個幫助子類是代理者這一資訊區域性化的時候。

Abstract Factory
  意圖 : 提供一個建立一系列相關或相互依賴物件的介面,而無需指定它們具體的類。

  適用性: 一個系統要獨立於它的產品的建立、組合和表示時。

  一個系統要由多個產品系列中的一個來配置時。

  當你要強調一系列相關的產品物件的設計以便進行聯合使用時。

  當你提供一個產品類庫,而只想顯示它們的介面而不是實現時。

Builder
  意圖 : 將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。

  適用性: 當建立複雜物件的演算法應該獨立於該物件的組成部分以及它們的裝配方式時。

  當構造過程必須允許被構造的物件有不同的表示時。

Prototype
  意圖: 用原型例項指定建立物件的種類,並且通過拷貝這些原型建立新的物件。

  適用性: 當要例項化的類是在執行時刻指定時,例如,通過動態裝載;或者

  為了避免建立一個與產品類層次平行的工廠類層次時;或者

  當一個類的例項只能有幾個不同狀態組合中的一種時。建立相應數目的原型並克隆它們可能比每次用合適的狀態手工例項化該類更方便一些。

Singleton
  意圖 : 保證一個類僅有一個例項,並提供一個訪問它的全域性訪問點。

  適用性: 當類只能有一個例項而且客戶可以從一個眾所周知的訪問點訪問它時。

  當這個唯一例項應該是通過子類化可擴充套件的,並且客戶應該無需更改程式碼就能使用一個擴充套件的例項時。

Adapter
  意圖: 將一個類的介面轉換成客戶希望的另外一個介面。A d a p t e r 模式使得原本由於介面不相容而不能一起工作的那些類可以一起工作。

  適用性: 你想使用一個已經存在的類,而它的介面不符合你的需求。

  你想建立一個可以複用的類,該類可以與其他不相關的類或不可預見的類(即那些介面可能不一定相容的類)協同工作。

  (僅適用於物件A d a p t e r )你想使用一些已經存在的子類,但是不可能對每一個都進行子類化以匹配它們的介面。物件介面卡可以適配它的父類介面。

Bridge
  意圖 : 將抽象部分與它的實現部分分離,使它們都可以獨立地變化。

  適用性 : 你不希望在抽象和它的實現部分之間有一個固定的繫結關係。例如這種情況可能是因為,在程式執行時刻實現部分應可以被選擇或者切換。

  類的抽象以及它的實現都應該可以通過生成子類的方法加以擴充。這時B r i d g e 模式使你可以對不同的抽象介面和實現部分進行組合,並分別對它們進行擴充。

  對一個抽象的實現部分的修改應對客戶不產生影響,即客戶的程式碼不必重新編譯。

  (C + +)你想對客戶完全隱藏抽象的實現部分。在C + +中,類的表示在類介面中是可見的。

  有許多類要生成。這樣一種類層次結構說明你必須將一個物件分解成兩個部分。R u m b a u g h 稱這種類層次結構為“巢狀的普化”(nested generalizations )。

  你想在多個物件間共享實現(可能使用引用計數),但同時要求客戶並不知道這一點。一個簡單的例子便是C o p l i e n 的S t r i n g 類[ C o p 9 2 ],在這個類中多個物件可以共享同一個字串表示(S t r i n g R e p )。

Composite
  意圖: 將物件組合成樹形結構以表示“部分-整體”的層次結構。C o m p o s i t e 使得使用者對單個物件和組合物件的使用具有一致性。

  適用性: 你想表示物件的部分-整體層次結構。

  你希望使用者忽略組合物件與單個物件的不同,使用者將統一地使用組合結構中的所有物件。

Decorator
  意圖: 動態地給一個物件新增一些額外的職責。就增加功能來說,D e c o r a t o r 模式相比生成子類更為靈活。

  適用性: 在不影響其他物件的情況下,以動態、透明的方式給單個物件新增職責。

  處理那些可以撤消的職責。

  當不能採用生成子類的方法進行擴充時。一種情況是,可能有大量獨立的擴充套件,為支援每一種組合將產生大量的子類,使得子類數目呈爆炸性增長。另一種情況可能是因為類定義被隱藏,或類定義不能用於生成子類。

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 進行通訊,從而簡化了它們之間的依賴關係。

Flyweight
  意圖 : 運用共享技術有效地支援大量細粒度的物件。

  適用性 : 一個應用程式使用了大量的物件。

  完全由於使用大量的物件,造成很大的儲存開銷。

  物件的大多數狀態都可變為外部狀態。

  如果刪除物件的外部狀態,那麼可以用相對較少的共享物件取代很多組物件。

  應用程式不依賴於物件標識。由於F l y w e i g h t 物件可以被共享,對於概念上明顯有別的物件,標識測試將返回真值。

Proxy
  意圖 : 為其他物件提供一種代理以控制對這個物件的訪問。

  適用性 : 在需要用比較通用和複雜的物件指標代替簡單的指標的時候,使用P r o x y 模式。下面是一 些可以使用P r o x y 模式常見情況:

  1) 遠端代理(Remote Proxy )為一個物件在不同的地址空間提供區域性代表。 NEXTSTEP[Add94] 使用N X P r o x y 類實現了這一目的。Coplien[Cop92] 稱這種代理為“大使” (A m b a s s a d o r )。

  2 )虛代理(Virtual Proxy )根據需要建立開銷很大的物件。在動機一節描述的I m a g e P r o x y 就是這樣一種代理的例子。

  3) 保護代理(Protection Proxy )控制對原始物件的訪問。保護代理用於物件應該有不同 的訪問許可權的時候。例如,在C h o i c e s 作業系統[ C I R M 9 3 ]中K e m e l P r o x i es 為作業系統物件提供 了訪問保護。

  4 )智慧指引(Smart Reference )取代了簡單的指標,它在訪問物件時執行一些附加操作。 它的典型用途包括:

  對指向實際物件的引用計數,這樣當該物件沒有引用時,可以自動釋放它(也稱為S m a r tP o i n t e r s[ E d e 9 2 ] )。

  當第一次引用一個持久物件時,將它裝入記憶體。

  在訪問一個實際物件前,檢查是否已經鎖定了它,以確保其他物件不能改變它。

Chain ofResponsibility
  意圖: 使多個物件都有機會處理請求,從而避免請求的傳送者和接收者之間的耦合關係。將這些物件連成一條鏈,並沿著這條鏈傳遞該請求,直到有一個物件處理它為止。

  適用性: 有多個的物件可以處理一個請求,哪個物件處理該請求執行時刻自動確定。

  你想在不明確指定接收者的情況下,向多個物件中的一個提交一個請求。

  可處理一個請求的物件集合應被動態指定。

Command
  意圖: 將一個請求封裝為一個物件,從而使你可用不同的請求對客戶進行引數化;對請求排隊或記錄請求日誌,以及支援可撤消的操作。

  適用性 : 像上面討論的M e n u I t e m 物件那樣,抽象出待執行的動作以引數化某物件。你可用過程語言中的回撥(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 有一個公共的介面,使得你可以用同一種方式呼叫所有的事務。同時使用該模式也易於新增新事務以擴充套件系統。

Interpreter
  意圖 : 給定一個語言,定義它的文法的一種表示,並定義一個直譯器,這個直譯器使用該表示來解釋語言中的句子。

  適用性 : 當有一個語言需要解釋執行, 並且你可將該語言中的句子表示為一個抽象語法樹時,可使用直譯器模式。而當存在以下情況時該模式效果最好:

  該文法簡單對於複雜的文法, 文法的類層次變得龐大而無法管理。此時語法分析程式生成器這樣的工具是更好的選擇。它們無需構建抽象語法樹即可解釋表示式, 這樣可以節省空間而且還可能節省時間。

  效率不是一個關鍵問題最高效的直譯器通常不是通過直接解釋語法分析樹實現的, 而是首先將它們轉換成另一種形式。例如,正則表示式通常被轉換成狀態機。但即使在這種情況下, 轉換器仍可用直譯器模式實現, 該模式仍是有用的。

Iterator
  意圖 :提供一種方法順序訪問一個聚合物件中各個元素, 而又不需暴露該物件的內部表示。

  適用性: 訪問一個聚合物件的內容而無需暴露它的內部表示。

  支援對聚合物件的多種遍歷。

  為遍歷不同的聚合結構提供一個統一的介面(即, 支援多型迭代)。

Mediator
  意圖: 用一箇中介物件來封裝一系列的物件互動。中介者使各物件不需要顯式地相互引用,從而使其耦合鬆散,而且可以獨立地改變它們之間的互動。

  適用性: 一組物件以定義良好但是複雜的方式進行通訊。產生的相互依賴關係結構混亂且難以理解。

  一個物件引用其他很多物件並且直接與這些物件通訊,導致難以複用該物件。

  想定製一個分佈在多個類中的行為,而又不想生成太多的子類。

Memento
  意圖: 在不破壞封裝性的前提下,捕獲一個物件的內部狀態,並在該物件之外儲存這個狀態。這樣以後就可將該物件恢復到原先儲存的狀態。

  適用性: 必須儲存一個物件在某一個時刻的(部分)狀態, 這樣以後需要時它才能恢復到先前的狀態。

  如果一個用介面來讓其它物件直接得到這些狀態,將會暴露物件的實現細節並破壞物件的封裝性。

Observer
  意圖: 定義物件間的一種一對多的依賴關係,當一個物件的狀態發生改變時, 所有依賴於它的物件都得到通知並被自動更新。

  適用性 :當一個抽象模型有兩個方面, 其中一個方面依賴於另一方面。將這二者封裝在獨立的物件中以使它們可以各自獨立地改變和複用。

  當對一個物件的改變需要同時改變其它物件, 而不知道具體有多少物件有待改變。

  當一個物件必須通知其它物件,而它又不能假定其它物件是誰。換言之, 你不希望這些物件是緊密耦合的。

State
  意圖: 允許一個物件在其內部狀態改變時改變它的行為。物件看起來似乎修改了它的類。

  適用性: 一個物件的行為取決於它的狀態, 並且它必須在執行時刻根據狀態改變它的行為。

  一個操作中含有龐大的多分支的條件語句,且這些分支依賴於該物件的狀態。這個狀態通常用一個或多個列舉常量表示。通常, 有多個操作包含這一相同的條件結構。S t a t e模式將每一個條件分支放入一個獨立的類中。這使得你可以根據物件自身的情況將物件的狀態作為一個物件,這一物件可以不依賴於其他物件而獨立變化。

Strategy
  意圖 :定義一系列的演算法,把它們一個個封裝起來, 並且使它們可相互替換。本模式使得演算法可獨立於使用它的客戶而變化。

  適用性 : 許多相關的類僅僅是行為有異。“策略”提供了一種用多個行為中的一個行為來配置一個類的方法。

  需要使用一個演算法的不同變體。例如,你可能會定義一些反映不同的空間/時間權衡的演算法。當這些變體實現為一個演算法的類層次時[ H O 8 7 ] ,可以使用策略模式。

  演算法使用客戶不應該知道的資料。可使用策略模式以避免暴露覆雜的、與演算法相關的資料結構。

  一個類定義了多種行為, 並且這些行為在這個類的操作中以多個條件語句的形式出現。將相關的條件分支移入它們各自的S t r a t e g y 類中以代替這些條件語句。

Template Method
  意圖: 定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中。Te m p l a t e M e th o d 使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。

  適用性 : 一次性實現一個演算法的不變的部分,並將可變的行為留給子類來實現。

  各子類中公共的行為應被提取出來並集中到一個公共父類中以避免程式碼重複。這是O p d y k e 和J o h n s o n 所描述過的“重分解以一般化”的一個很好的例子[ O J 9 3 ]。首先識別現有程式碼中的不同之處,並且將不同之處分離為新的操作。最後,用一個呼叫這些新的操作的模板方法來替換這些不同的程式碼。

  控制子類擴充套件。模板方法只在特定點呼叫“h o o k ”操作(參見效果一節),這樣就只允許在這些點進行擴充套件。

Visitor
  意圖 :表示一個作用於某物件結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用於這些元素的新操作。

  適用性: 一個物件結構包含很多類物件,它們有不同的介面,而你想對這些物件實施一些依賴於其具體類的操作。

  需要對一個物件結構中的物件進行很多不同的並且不相關的操作,而你想避免讓這些操作“汙染”這些物件的類。Vi s i t o r 使得你可以將相關的操作集中起來定義在一個類中。當該物件結構被很多應用共享時,用Vi s i t o r 模式讓每個應用僅包含需要用到的操作。

  定義物件結構的類很少改變,但經常需要在此結構上定義新的操作。改變物件結構類需要重定義對所有訪問者的介面,這可能需要很大的代價。如果物件結構類經常改變,那麼可能還是在這些類中定義這些操作較好。

形象比喻

ABSTRACT FACTORY

  追MM少不了請吃飯了,麥當勞的雞翅和肯德基的雞翅都是MM愛吃的東西,雖然口味有所不同,但不管你帶MM去麥當勞或肯德基,只管向服務員說“來四個雞翅”就行了。麥當勞和肯德基就是生產雞翅的Factory

  工廠模式:客戶類和工廠類分開。消費者任何時候需要某種產品,只需向工廠請求即可。消費者無須修改就可以接納新產品。缺點是當產品修改時,工廠類也要做相應的修改。如:如何建立及如何向客戶端提供。

BUILDER

  MM最愛聽的就是“我愛你”這句話了,見到不同地方的MM,要能夠用她們的方言跟她說這句話哦,我有一個多種語言翻譯機,上面每種語言都有一個按鍵,見到MM我只要按對應的鍵,它就能夠用相應的語言說出“我愛你”這句話了,國外的MM也可以輕鬆搞定,這就是我的“我愛你 ”builder。(這一定比美軍在伊拉克用的翻譯機好賣)

  建造者模式:將物件的內部表象和物件的生成過程分割開來,從而使一個建造過程生成具有不同的內部表象的產品物件。建造模式使得產品內部表象可以獨立的變化,客戶不必知道產品內部組成的細節。建造模式可以強制實行一種分步驟進行的建造過程。

FACTORY METHOD

  請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過生日,還是不要叫她自己挑了,不然這個月伙食費肯定玩完,拿出我去年在華山頂上照的照片,在背面寫上“最好的的禮物,就是愛你的Fita”,再到街上禮品店買了個像框(賣禮品的MM也很漂亮哦),再找隔壁搞美術設計的Mike設計了一個漂亮的盒子裝起來……,我們都是Decorator,最終都在修飾我這個人呀,怎麼樣,看懂了嗎?

  裝飾模式:裝飾模式以對客戶端透明的方式擴充套件物件的功能,是繼承關係的一個替代方案,提供比繼承更多的靈活性。動態給一個物件增加功能,這些功能可以再動態的撤消。增加由一些基本功能的排列組合而產生的非常大量的功能。

FACADE

  我有一個專業的Nikon相機,我就喜歡自己手動調光圈、快門,這樣照出來的照片才專業,但MM可不懂這些,教了半天也不會。幸好相機有Facade設計模式,把相機調整到自動檔,只要對準目標按快門就行了,一切由相機自動調整,這樣MM也可以用這個相機給我拍張照片了。

  門面模式:外部與一個子系統的通訊必須通過一個統一的門面物件進行。門面模式提供一個高層次的介面,使得子系統更易於使用。每一個子系統只有一個門面類,而且此門面類只有一個例項,也就是說它是一個單例模式。但整個系統可以有多個門面類。

FLYWEIGHT

  每天跟MM發簡訊,手指都累死了,最近買了個新手機,可以把一些常用的句子存在手機裡,要用的時候,直接拿出來,在前面加上MM的名字就可以傳送了,再不用一個字一個字敲了。共享的句子就是Flyweight,MM的名字就是提取出來的外部特徵,根據上下文情況使用。

  享元模式:FLYWEIGHT在拳擊比賽中指最輕量級。享元模式以共享的方式高效的支援大量的細粒度物件。享元模式能做到共享的關鍵是區分內蘊狀態和外蘊狀態。內蘊狀態儲存在享元內部,不會隨環境的改變而有所不同。外蘊狀態是隨環境的改變而改變的。外蘊狀態不能影響內蘊狀態,它們是相互獨立的。將可以共享的狀態和不可以共享的狀態從常規類中區分開來,將不可以共享的狀態從類裡剔除出去。客戶端不可以直接建立被共享的物件,而應當使用一個工廠物件負責建立被共享的物件。享元模式大幅度的降低記憶體中物件的數量。

PROXY

  跟MM在網上聊天,一開頭總是“hi,你好”,“你從哪兒來呀?”“你多大了?”“身高多少呀?”這些話,真煩人,寫個程式做為我的Proxy吧,凡是接收到這些話都設定好了自動的回答,接收到其他的話時再通知我回答,怎麼樣,酷吧。

  代理模式:代理模式給某一個物件提供一個代理物件,並由代理物件控制對源物件的引用。代理就是一個人或一個機構代表另一個人或者一個機構採取行動。某些情況下,客戶不想或者不能夠直接引用一個物件,代理物件可以在客戶和目標物件直接起到中介的作用。客戶端分辨不出代理主題物件與真實主題物件。代理模式可以並不知道真正的被代理物件,而僅僅持有一個被代理物件的介面,這時候代理物件不能夠建立被代理物件,被代理物件必須有系統的其他角色代為建立並傳入。

CHAIN OFRESPONSIBLEITY

  晚上去上英語課,為了好開溜坐到了最後一排,哇,前面坐了好幾個漂亮的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 METHOD

  模板方法模式:模板方法模式準備一個抽象類,將部分邏輯以具體方法以及具體構造子的形式實現,然後宣告一些抽象方法來迫使子類實現剩餘的邏輯。不同的子類可以以不同的方式實現這些抽象方法,從而對剩餘的邏輯有不同的實現。先制定一個頂級邏輯框架,而將邏輯的細節留給具體的子類去實現。

VISITOR

  情人節到了,要給每個MM送一束鮮花和一張卡片,可是每個MM送的花都要針對她個人的特點,每張卡片也要根據個人的特點來挑,我一個人哪搞得清楚,還是找花店老闆和禮品店老闆做一下Visitor,讓花店老闆根據MM的特點選一束花,讓禮品店老闆也根據每個人特點選一張卡,這樣就輕鬆多了;

  訪問者模式:訪問者模式的目的是封裝一些施加於某種資料結構元素之上的操作。一旦這些操作需要修改的話,接受這個操作的資料結構可以保持不變。訪問者模式適用於資料結構相對未定的系統,它把資料結構和作用於結構上的操作之間的耦合解脫開,使得操作集合可以相對自由的演化。訪問者模式使得增加新的操作變的很容易,就是增加一個新的訪問者類。訪問者模式將有關的行為集中到一個訪問者物件中,而不是分散到一個個的節點類中。當使用訪問者模式時,要將盡可能多的物件瀏覽邏輯放在訪問者類中,而不是放到它的子類中。訪問者模式可以跨過幾個類的等級結構訪問屬於不同的等級結構的成員類。

設計模式的六大原則

1、開閉原則(Open Close Principle)

  開閉原則就是說對擴充套件開放,對修改關閉。在程式需要進行拓展的時候,不能去修改原有的程式碼,實現一個熱插拔的效果。所以一句話概括就是:為了使程式的擴充套件性好,易於維護和升級。想要達到這樣的效果,我們需要使用介面和抽象類,後面的具體設計中我們會提到這點。
  一個軟體實體如類、模組和函式應該對擴充套件開放,對修改關閉。當軟體需要變化時,儘量通過擴充套件軟體實體的行為來實現變化,而不是通過修改已有的程式碼來實現變化。

2、里氏代換原則(Liskov Substitution Principle)

  里氏代換原則(Liskov Substitution Principle LSP)面向物件設計的基本原則之一。 里氏代換原則中說,任何基類可以出現的地方,子類一定可以出現。 LSP是繼承複用的基石,只有當衍生類可以替換掉基類,軟體單位的功能不受到影響時,基類才能真正被複用,而衍生類也能夠在基類的基礎上增加新的行為。里氏代換原則是對“開-閉”原則的補充。實現“開-閉”原則的關鍵步驟就是抽象化。而基類與子類的繼承關係就是抽象化的具體實現,所以里氏代換原則是對實現抽象化的具體步驟的規範。
  所有引用基類的地方必須能透明地使用其子類的物件。儘量不要重寫\過載父類方法.

3、依賴倒轉原則(Dependence Inversion Principle)

  這個是開閉原則的基礎,具體內容:真對介面程式設計,依賴於抽象而不依賴於具體。
  即高層模組不應該依賴低層模組,二者都應該依賴其抽象;抽象不應該依賴細節;細節應該依賴抽象。

4、介面隔離原則(Interface Segregation Principle)

  這個原則的意思是:使用多個隔離的介面,比使用單個介面要好。還是一個降低類之間的耦合度的意思,從這兒我們看出,其實設計模式就是一個軟體的設計思想,從大型軟體架構出發,為了升級和維護方便。所以上文中多次出現:降低依賴,降低耦合。
  客戶端不應該依賴它不需要的介面;一個類對另一個類的依賴應該建立在最小的介面上。

5、迪米特法則(最少知道原則)(Demeter Principle)

  為什麼叫最少知道原則,就是說:一個實體應當儘量少的與其他實體之間發生相互作用,使得系統功能模組相對獨立。
   一個物件應該對其他物件保持最少的瞭解。 儘量降低類與類之間的耦合。

6、合成複用原則(Composite Reuse Principle

  原則是儘量使用合成/聚合的方式,而不是使用繼承。
  一個類應該僅有一個引起它變化的原因

相關推薦

JAVA 23設計模式簡介

  設計模式(Design Patterns) ——可複用面向物件軟體的基礎   設計模式(Design pattern)是一套被反覆使用、多數人知曉的、經過分類編目的、程式碼設計經驗的總結。使用設計模式是為了可重用程式碼、讓程式碼更容易被他人理解、保證程式碼

java 23設計模式

代理 建造者 學習 article 適配器 htm ava arc 叠代 備註這是別人總結的本來想轉載可惜不會怎麽轉載(感謝) 以下是學習過程中查詢的資料,別人總結的資料,比較容易理解(站在各位巨人的肩膀上,望博主勿究) 創建型抽象工廠模式 http://www.cnblo

兩週多學完Java 23設計模式

       最近兩週任務不是很繁重,對於一個剛入職4個月的菜鳥來說,學習設計模式並靈活使用簡直天方夜譚;但是當我詢問我導師需要學點啥的時候?“《Java設計模式》,這個必須要學”,一句簡單粗略的話就打發我了。我花了將近兩週多的時間看了一部分《Java設計

兩周多學完Java 23設計模式

橋接 總結 .net 機制 接下來 策略模式 行為型模式 java 享元    最近兩周任務不是很繁重,對於一個剛入職4個月的菜鳥來說,學習設計模式並靈活使用簡直天方夜譚;但是當我詢問我導師需要學點啥的時候?“《Java設計模式》,這個必須要學”,一句簡單粗略的話就打發

JAVA 23設計模式---工廠模式(簡單工廠模式)

寫在前面的話: java常用的設計模式有23種,設計模式就是為了重用程式碼、解耦、讓程式碼更容易讓他人理解、保證程式碼可靠性 設計模式遵循的原則有6個: 1、開閉原則(Open Close Principle)   對擴充套件開放,對修改關閉。 2、里氏代換原則(Liskov S

java 23設計模式--代理模式

代理模式 為其他物件提供一種代理以控制對此物件的訪問 Subject類:定義了RealSubject類和proxy類共同的介面,這樣就可以在任何使用RealSubject的地方都可以使用proxy; public interface Subject{ /** *

Java 23設計模式對比總結

一、設計模式的分類 建立型模式,共五種(1-5):工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。  結構型模式,共七種(6-12):介面卡模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。  行為型模式,共十一種(13-23):策略模式、模板方法模式、觀察者模

java 23設計模式 深入理解

strong 觀察 結構型 工廠 設計模式 .html 外觀 資料 訪問者模式 以下是學習過程中查詢的資料,別人總結的資料,比較容易理解(站在各位巨人的肩膀上,望博主勿究) 創建型抽象工廠模式 http://www.cnblogs.com/java-my-life/arch

java 23設計模式詳解

設計模式的分類 總體來說設計模式分為三大類: 建立型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。 結構型模式,共七種:介面卡模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。 行為型模式,共十一種:策略模式

iOS 開發常用的23設計模式簡介

//聯絡人:石虎 QQ:1224614774 暱稱:嗡嘛呢叭咪哄 一、概念  設計模式主要分三個型別:建立型、結構型和行為型。 二、建立型有:  1.單例模式(Singlet

Java 23 設計模式

www. tar 模式 建造者 訪問者 blank 裝飾者 原型 arch 以下是學習過程中查詢的資料,別人總結的資料,比較容易理解(站在各位巨人的肩膀上,望博主勿究) 創建型抽象工廠模式 http://www.cnblogs.com/java-my-life/archiv

淺談java 23設計模式之模板方法模式(Template )

模板方法模式:模板方法模式是類的行為模式的一種,符合開閉原則(對擴充套件開放,對修改關閉)。父類提取子類公共方法,並提供若干抽象方法供子類實現,以減少子類中的重複程式碼,並提高可複用性。示例:1.建立一個父類bird,每天只有吃和睡才能生活,但是必須要先進行吃,然後再進行睡:

設計模式Java常用23設計模式及六大原則簡介

目錄 簡介 建立型模式 結構型模式 行為型模式 簡介 設計模式(Design pattern)代表了最佳的實踐,通常被有經驗的面向物件的軟體開發人員所採用。設計模式是軟體開發人員在軟體開發過程中面臨的一般問題的解決方案。這些解決方案是眾多軟體開發人員經

Java開發23設計模式

熱插拔 開發 每一個 設計模式 為什麽 之間 des 單位 行為型 設計模式(Design Patterns)       -- -- -- 可復用面向對象軟件的基礎 設計模式(Design Patterns)是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的

JAVA開發的23設計模式之 --- 橋接模式

橋接模式    概述:將抽象部分與他的實現部分分離,這樣抽象化與實現化解耦,使他們可以獨立的變化.如何實現解耦的呢,就是通過提供抽象化和實現化之間的橋接結構.    應用場景      &n

Java23設計模式(附代碼樣例)

體會 如何解決 熱插拔 原型 原型模式 strac println template sendmai 一、設計模式分類總體來說設計模式分為三大類:創建型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。結構型模式,共七種:適配器模式、裝飾器模式、代理

java23設計模式之裝飾者模式

這裡給大家推薦一篇文章裡面介紹了23種設計模式https://www.aliyun.com/jiaocheng/811770.html; 下面則是我學習裝飾者的見解: 關於裝飾者模式運用的地方其實有很多,我第一次接觸到就是io流中,比如像這樣的: new InputStreamRea

JAVA設計模式總結之23設計模式

ret 都對 松耦合 mem ava htm 初學者 並不是 不用 一、什麽是設計模式

java開發-23設計模式之菜鳥解析1

java開發有23種設計模式,很多工齡沒那麼長的java開發程式設計師可能都不會特意去了解它們,其實它存在的意義不只是應對各種面試,而是在開發過程中簡化、邏輯化、分類化你的程式碼,讓你的程式碼可讀性更高,為你的開發帶來便利的東西。廢話不多說,開始正題 首先大家要了解設計模式的分類,一般分為三個型

JAVA 23設計設計模式---工廠模式(工廠方法)

設計模式中的工廠模式可大致分為3個,簡單工廠、工廠方法、抽象工廠。 今天整理的是工廠方法模式,介紹如下: 案列結構如下: 程式碼結構如下:   卡車: package com.zxf.method; //卡車(介面) public interfac