創造性模式算法
結構模式設計模式
*行爲模式數組
對可重用性和可維護性設計模式的高層考慮緩存
工廠方法模式
也稱爲「虛擬構造器」服務器
意圖:ide
何時應該使用工廠方法? ----當一個類:函數
當客戶不知道要建立哪一個具體類的實例,或者不想在客戶代碼中指明具體建立的實例時,用工廠方法。定義一個用於建立對象的接口,讓其子類來決定實例化哪個類 ,從而使一個類的實例化延遲到其子類。工具
優勢:佈局
潛在的缺點優化
Open-Closed Principle(OCP) - 對擴展的開放,對修改已有代碼的封閉
抽象工廠模式
示例1:考慮一個用戶界面工具包,它支持不一樣操做系統的多個外觀和感受標準:一個UI,包含多個窗口控件,這些控件在不一樣的OS中實現不一樣
示例2:考慮支持不一樣控制系統的智能住宅的設施管理系統:一個倉庫類,要控制多個設備,這些設備的製造商各有不一樣,控制接口有差別
抽象工廠模式:提供接口以建立一組相關/相互依賴的對象,但不須要指明其具體類。
名稱:抽象工廠(或工具包)
意圖:容許獨立於實現建立相關對象的家族
方法:使用工廠返回可用於建立相關對象集的工廠。
適用性
筆記
Abstract Factory建立的不是一個完整產品,而是「遵循固定搭配規則的多類產品的實例」,獲得的結果是:多個不一樣產品的對象,各產品建立過程對客戶可見,但「搭配」不能改變。
本質上,Abstract Factory是把多類產品的工廠方法組合在一塊兒
例如
GraphPoet由Word列表和WordNeighborhood列表組成
NetworkTopology由計算機/服務器/路由器列表和NetworkConnection列表組成
換句話說,Vertex和Edge的對象建立密切相關,但不該該是獨立的。 Vertex和Edge的子類,要有固定搭配,不能隨意組合
抽象工廠vs工廠方法
工廠方法僅用於建立一個產品,但抽象工廠用於建立相關或依賴產品系列。
工廠方法模式向客戶端公開建立對象的方法,而抽象工廠則顯示由這些工廠方法組成的一系列相關對象。
抽象工廠模式使用組合來將建立對象的責任委派給另外一個類,而工廠方法模式使用繼承並依賴於派生類或子類來建立對象。
構造器模式
構造器模式:將複雜對象的構造與其表示分開,以便相同的構建過程能夠建立不一樣的表示。建立複雜對象,包含多個組成部分
示例:將文檔轉換爲多種不一樣的格式
就像你在麥當勞點餐同樣!
途徑
注意:客戶端要的不是一堆零散的對象(抽象工廠那樣的結果),而是一個完整的產品,客戶端不關心其中的細節組成部分是什麼,如何建立
比較:抽象工廠vs構造器
Abstract Factory建立的不是一個完整產品,而是「遵循固定搭配規則的多類產品實例」,獲得的結果是:多個不一樣產品的實例對象,各產品建立過程對客戶可見,但「搭配」不能改變。
Builder建立的是一個完整的產品,有多個部分組成,客戶不須要了解每一個部分是怎麼建立,各個部分怎麼組合,最終獲得一個產品的完整對象
抽象工廠和構造器能夠很好地協同工做,適用於多種複雜產品系列
例如
GraphPoet由Word列表和WordNeighborhood列表組成
NetworkTopology由計算機/服務器/路由器列表和NetworkConnection列表組成
換句話說,ConcreteGraph的對象建立由Vertex和Edge子類型的對象建立組成。 四個圖應用都要建立圖對象,要爲不一樣應用創建出不一樣的頂點列表和邊列表。
比較:模板方法vs構造器
模板方法:行爲模式,目標是爲了複用算法的公共結構(次序)
Builder:一種創造模式,目標是「建立複雜對象」,靈活擴展
橋接模式
適用性
結構:使用兩個層次結構
對象:提升可擴展性
橋接模式是OOP最基本的結構模式,經過委託+繼承創建兩個具體類之間的關係(DIP依賴轉置,抽象依賴於抽象)
橋接模式與策略模式
橋接:結構模式,強調雙方的運行時委派鏈接
一個類A的對象中有其餘類B的對象做爲其組成部分,但A的對象具體綁定到B的哪一個具體子類的實現?在運行時經過委託加以組合,並永久保存這種代理關係。
策略:行爲模式,強調一方運行時使用另外一方的「算法」
「算法」一般實現爲「類的某個方法」的形式,策略模式的目的並不是在「調用算法的類」與「被調用算法所在的類」之間創建起永久聯繫,而只是幫助前者臨時使用後者中的「算法」,前者無需永久保存後者的實例。
策略:使用螺絲刀的時候,針對不一樣的工做任務,選取不一樣的「刀頭」,但目的並不是將螺絲刀與刀頭組合起來創建永久的團隊,而只是臨時經過委派完成任務(即調用刀頭的「算法」),而後兩者再無聯繫。
橋接:類A須要完成「通信」功能,它有一個組成部分Device類,這是個抽象接口(模式中的實現者),有多種實現方式(PC,tablet,phone,即ConcreteImplementor),該模式在運行時爲類A的具體子類型實例設定具體的Device的具體實現(強調對A和Device兩個抽象類的各自實例之間如何創建委託),進而在其餘各項功能中利用其通信功能(這再也不是橋接模式關注的目標)。
代理模式
代理模式動機
目標:
解決方案:
某個對象比較「敏感」/「私密」/「貴重」,不但願被客戶端直接訪問到,故設置代理,在兩者之間創建防火牆。
代理模式:3種類型
信息緩存(「遠程代理」)
Standin(「虛擬代理」)
訪問控制(「保護代理」)
代理與適配器
適配器:結構模式,目的是將類/庫A的接口更改成客戶端B的指望。
目的:消除不兼容,目的是B以客戶端指望的統一的方式與A創建起聯繫。
代理:行爲模式,也使用包裝類,但其目的是爲實際資源建立一個替身。
目的:隔離對複雜對象的訪問,下降難度/代價,定位在「訪問/使用行爲」
組合模式
問題:
意圖:將對象組成樹結構以表示總體部分層次結構。
組合策略
包含菜單項的菜單,每一個菜單項均可以是菜單。
包含小部件的行列GUI佈局管理器,每一個小部件均可以是行列GUI佈局管理器。
包含文件的目錄,每一個文件均可以是一個目錄。
包含元素的容器,其中每一個容器均可以是容器。
樹結構
複合vs裝飾器
複合:結構模式,容許您以容許外部代碼將整個結構視爲單個實體的方式構建分層結構(樹)。目的是在同類型的對象之間創建起樹型層次結構,一個上層對象可包含多個下層對象
裝飾器:結構模式,也容許一個實體徹底包含另外一個實體,以便使用裝飾器看起來與包含的實體相同。強調的是同類型對象之間的「特性增長」問題,它們之間是平等的,區別在於「擁有特性」的多少,每次裝飾只能做用於一個對象。
觀察者模式
問題:依賴的狀態必須與主人的狀態一致
解決方案:定義四種對象:
「粉絲」對「偶像」感興趣,但願隨時得知偶像的一舉一動
粉絲到偶像那裏註冊,偶像一旦有新聞發生,就推送給已註冊的粉絲(回調粉絲的特定功能)
建模對象之間的一對多依賴關係
用法:
保持一致性的三個變體:
也稱爲發佈 - 訂閱(Publish-ubscribe)。
優勢:
實施問題
訪客模式
訪問者模式:容許在運行時將一個或多個操做應用於一組對象,將操做與對象結構分離。 對特定類型的對象的特定操做(訪問),在運行時將兩者動態綁定到一塊兒,該操做能夠靈活更改,無需更改被訪問的類
本質上:將數據和做用於數據上的某種/些特定操做分離開來。
訪客與迭代器
迭代器:行爲模式,用於順序訪問彙集,而不暴露其基礎表示。 因此你能夠在一個Iterator後面隱藏一個List或數組或相似的聚合。
迭代器:以遍歷的方式訪問集合數據而無需暴露其內部表示,將「遍歷」這項功能委託到外部的迭代器對象。
訪問者:行爲模式,用於對元素結構執行操做而不改變元素自己的實現。
在特定ADT上執行某種特定操做,但該操做不在ADT內部實現,而是委託到獨立的訪客對象,客戶端可靈活擴展/改變訪問者的操做算法,而不影響ADT
策略vs訪客
訪客:行爲模式
策略:行爲模式
兩者都是經過受權創建兩個對象的動態聯繫
區別:訪客是站在外部客戶的角度,靈活增長對ADT的各類不一樣操做(哪怕ADT沒實現該操做),策略是站在內部ADT的角度,靈活變化對其內部功能的不一樣配置。
中介模式
使用中央控制器是中介模式的關鍵方面。
經過封裝不一樣對象集相互交互和通訊的方式,容許鬆耦合。
觀察者模式與中介模式
觀察者模式:定義對象之間的一對多依賴關係,以便當一個對象改變狀態時,它的全部依賴項都會被自動通知和更新。
一組對象對另外一個對象B的狀態變化感興趣(1對多),因此對其進行觀察.B維持着一個對本身感興趣的對象列表,一旦本身發生變化,就通知這些對象。並不對等,一方只是「通知」,另外一方接到通知後執行特定行爲。
中介模式:定義一個封裝一組對象如何交互的對象。介體經過讓對象明確地互相引用來促進鬆散耦合,而且可讓您獨立地改變它們的相互做用。
一組同類型的對象,彼此之間相互發/收消息(多對多),不存在誰觀察誰的問題,全部對象都對等。每一個對象都維持一箇中介,將通信的任務委託給它,本身只負責發送和接收便可,無需瞭解其餘物體,實現了「解耦」。
觀察者模式:本身來廣播,其餘對象接收;
中介模式:第三方中介負責廣播(相似於「郵件列表」)。
命令
意圖
將「指令」封裝爲對象,指令的全部細節對客戶隱藏,在指令內對具體的ADT發出動做(調用ADT的細節操做)
問題
客戶端但願執行指令,但不想知道指令的細節,也不想知道指令的具體做用對象
命令將調用操做的對象與知道如何執行操做的對象分離。
每當客戶端須要對象的「服務」時,Command對象的全部客戶端都經過簡單地調用對象的虛擬execute()方法將每一個對象視爲「黑盒子」。
將全部對客戶提供的指令與內部執行的ADT操做完全分開,指令對外看來是「黑盒」 - 進一步「變本加厲」的封裝!
一個Command類包含如下的一些子集:
外觀與命令
外觀:結構模式
命令:行爲模式
均強調對某個複雜系統內部提供的功能的「封裝」,對外提供簡單的調用接口,簡化客戶端的使用,「隱藏」細節。
命令:強調將指令封裝爲了「對象」,提供了統一的對外接口(執行)。
外觀:沒有顯式的「對象」,仍然經過類的方法加以調用。
責任鏈模式
問題
針對一個請求,可能有多個處理模塊
各類不肯定狀況存在,不能以「硬編碼」的方式指明按何種次序調用處理模塊
意圖
避免在請求方和各處理者之間的緊耦合:構造流水線,請求在其上傳,直到被處理爲止。
將處理元素封裝在「管道」抽象中; 並讓客戶在管道入口處「啓動並離開」他們的請求。
客戶端只需在流水線的入口發出請求便可,請求自動在流水線上傳遞,直到被處理。
該模式將接收對象連接在一塊兒,而後將任何請求消息從對象傳遞到對象,直到它到達可以處理消息的對象。
處理器對象的數據和類型事先都不肯定,須要動態配置
使用遞歸組合的方式,將多個處理程序連成「職責鏈」
責任鏈簡化了對象互連。
請求的發起者無需維護全部可能的處理程序對象,只需記錄職責鏈的入口;每一個處理程序只須要維護「下一個」處理程序便可,從而簡化了各個處理程序之間的鏈接關係。
訪客與責任鏈
不是像傳統類設計中將操做與數據捆綁在一塊兒造成ADT,這兩個設計模式都是將「數據」與「做用於數據上的客戶端定製操做」分離開來
緣由:操做能夠靈活增長,運行時使用的操做能夠動態配置,多個操做的執行次序能夠動態變化
區別1:visitor只定義了一個操做,chain of responsibility定義了一組操做及其之間的次序
區別2:訪客中,客戶建立訪客以後傳入ADT,ADT再將執行權委託到visitor;責任鏈中,控制權徹底在各個處理程序之間流轉,ADT(請求對象)徹底感覺不到。
文本:「獨立於製造商」,「獨立於設備」,「必須支持一系列產品」
=>抽象工廠模式
文本:「必須與現有對象接口」
=>適配器模式
文本:「必須與多個系統接口,其中一些系統將在將來開發」,「必須展現早期的原型」
=>橋模式
文本:「必須與現有的一組對象接口」
=>外牆模式
文本:「複雜結構」,「必須具備可變的深度和寬度」
=>複合模式
文本:「必須是位置透明的」
=>代理模式
文本:「必須可擴展」,「必須可擴展」
=>觀察者模式
文本:「必須提供獨立於該機制的政策」
=>策略模式
組合,適配器,橋接,包裝,代理(結構模式)
命令,觀察者,策略,模板(行爲模式)
抽象工廠,生成器(創造性模式)
創造性模式
結構模式
行爲模式
對可重用性和可維護性設計模式的高層考慮