设计模式的理解:对23个设计模式的总结
生活随笔
收集整理的這篇文章主要介紹了
设计模式的理解:对23个设计模式的总结
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
設計模式名 ,鏈接可用
文檔可下載:https://download.csdn.net/download/superSmart_Dong/16625368
| 設計模式 | 意圖 | 適用的場景 | 關鍵實現過程 | 優點 | 缺點 | 備注 | |
| 1 | 模板模式 | 通常定義出一個穩定的骨架,特定的內容的實現延遲至子類中去實現 | 易變,容易根據實際需求改動的代碼塊,對此代碼塊進行延遲到子類中實現 | 不變的算法在基類中保留,易變的算法變成虛函數由子類實現 | 把不確定部分剝離開來,實現確定的部分。讓將來的調用者簡單實現不確定的方法就可以達到想要的效果 | 對調用者屏蔽了穩定的代碼,使調用者雖了解使用方法但不易理解底層實現的邏輯 | 例如,線程:用戶不需要理解與硬件的關聯關系,只需要知道實現run方法就可以讓程序達到高效,并行的目的 |
| 2 | 策略模式 | 定義一系列算法,把他們用一個個類封裝起來,并使它們可以動態地相互替換. | 業務場景無法窮舉,卻要根據不同的場景做出不同的操作。 | 根據枚舉或者其他標志創建具體的派生類。用基類接收派生類,調用基類的方法。 | 減少了if..else的判斷,把各個分支的實現變成了派生類方法的實現。避免代碼臃腫,減小了需求變動、擴展的影響性 | 采用動態綁定會比編譯時綁定性能低些,但是可以忽略 | 可以窮舉的if...else 可以不需要用策略模式 |
| 3 | 觀察者模式 | 當下層結構需要向上層結構傳遞信號時,不應該將上層的變量傳遞到下層的方式實現。因為下層結構不應該依賴于上層結構 | 上層結構接收來自下層結構的信號,而返回值類型又不確定時 | 定義一個對信號操作的接口,信號數組是下層結構中的成員。上層結構繼承該接口,并將自身添加進下層結構的信號數組,從而接收下層結構的傳遞的信號 | 下層結構不直接依賴與上層結構 | ? | 例如進度條展示,下層架構需要對 已下載數量占總大小的百分比傳遞到上層。但是進度條可以是條狀的也可以菊花狀的,接收信號的數據類型并不確定。所以下層將信號傳進接口中,上層結構實現接口方法,操作 接口的輸入參數。 |
| 4 | 裝飾模式 | 動態的給對象擴展一些額外的職責 | 給基類添加功能后還是屬于基類的范疇 | 定義一個功能裝飾類繼承基類,同時成員屬性又包含基類類型。具體功能類繼承裝飾類,實現基類的方法,在實現過程中先實現自身的邏輯,最后再調用基類的方法。而成員基類抽象對象的賦值通過構造函數實現。 | 定義一個功能類,將原先的派生類傳遞到功能對象中,功能對象調用方法就可以達到目的。此模式可以隨意組合任意的方法,擺脫了繼承的濫用 | ? | 例如文件流,網絡流都繼承流這個對象,現新增一個加密功能來加密流的讀寫操作。那么這個加密功能封裝成類,繼承于流,并流又是加密類的成員。實現加密流的讀、寫方法后再調用流的抽象方法。 |
| 5 | 橋模式 | 當基類從多個不同維度派生時,不同維度間的聯系應該解耦 | 當基類需要從多個不同維度派生時 | 將基類的功能按照維度去拆分出不同的基類,各個基類時另外基類的成員 | 將基類的功能按照維度拆分后,各個維度進行了解耦。 | ? | 例如,一個類中用登錄功能和發送消息,播放聲音和播放動畫功能。當操作系統不一樣時播放聲音和播放動畫的功能不一樣,當用戶VIP等級不一樣時登錄功能和發送消息效果不一樣。那么就需要將類按照者兩個維度進行拆分成兩個基類,這兩個基類相互是對方的成員。 |
| 6 | 工廠模式 | 利用抽象類去動態地創建對象 | 與策略模式配合 | ? | ? | ? | ? |
| 7 | 抽象工廠模式 | 利用抽象類動態地創建一系列的對象 | 需要動態地創建一組對象時,每一組中的對象之間有緊密的聯系 | 對類中的每個對象用工廠模式創建。將創建標志用成員變量去存,之后就直接調用函數就行 | 用統一的創建標志保證了一系列對象間的關聯性 | ? | 例如DBConnection對象和DBCommand對象,不能將SQLConnection和DBCommand創建起來。 |
| 8 | 原型方法 | 通過深拷貝克隆出一個新的對象。操作時用新對象去操作,不影響原先對象 | 怕指針傳遞和指針傳遞的間接改變未知代碼的實參 | 實現抽象類的clone方法,進行深拷貝 | ? | ? | 在C++中還需需要實現深拷貝的拷貝構造函數 |
| 9 | 構造器模式 | 將一個復雜對象的構建與其表示分離,使得同樣的構建過程可以創建不同的表示 | 成員參數之間有一定的關聯性,會根據情況不同初始化不同部分的成員參數。并不是所有參數都必須初始化時。 | 創建內部類Builder,所有成員拷貝到Builder中,把必須初始化的參數設成Builder的構造函數,可選初始化的用鏈式set進行初始化。最后調用build方法,build方法把自身傳遞近原對象的構造函數中 | 把復雜的對象初始化變得簡單。 | ? | ? |
| 10 | 單例模式 | ①一個類只能初始化出一個對象?②保證對象是線程安全的。 | 要求只能被創建一次對象的類 | 所有成員和成員方法設成靜態,靜態成員有自身的引用,私有的構造函數和拷貝構造函數,靜態初始化函數需要保證線程安全。可以用返回局部靜態對象的方式來保證線程安全,但是在C++11不支持 | 保證了結構的規范化 | 線程安全是一個難題 | ? |
| 11 | 享元模式 | 使用大量細粒度對象時,代價過高性能變低的問題 | 粒度大的對象的創建,并且該對象的值經常使用的情況 | 對粒度大的對象或者對象屬性用引用的形式封裝起來,用緩存的形式讓對象或者對象屬性減少創建次數 | 減小創建對象的開銷 | 如果對象屬性每次都不一樣,對應的key值每次都不一樣一樣也會創建不少對象 | ? |
| 12 | 門面(外觀)模式 | 避免外部程序直接調用內部方法,對內部方法進行有效的屏蔽。 | 對外開放的內部方法多。并且容易根據需求而改變 | 用一個提供些專門進行對外訪問的接口,比如三層架構的BLL層 | ? | ? | ? |
| 13 | 代理模式 | 可以新增些特有的操作,而不用去修改原有對象邏輯 | 特例多 | 代理對象繼承于基類且成員有基類的引用,代理類可以實現基類的方法也可以使用基類的方法還可以新增特有的方法。 | 隔絕了外界用戶對實際對象的訪問 | ? | 例如:銀行卡、存折等不方便讓外界用戶訪問,但是外界用戶想存取錢,可以訪問支票對象。由支票對象間接的操作 |
| 14 | 適配器模式 | 為了轉變接口方式的一種模式。即通過一個中介,作為兩個不兼容接口之間的橋梁(老接口與新接口),使原先的老對象不僅可以使用自身的老接口,而且還可以通過適配器類,用新接口對老對象進行操作。 | 接口不一致 | 適配器類實現新接口,成員有原始類的引用。 | ? | ? | 例如電燈工作的輸入是電,如果用人想要讓電燈工作的輸入是聲音.那么定義輸入聲音的接口,適配器實現該接口,輸入是聲音,然后把聲音轉成電,最后再調用電燈的方法 |
| 15 | 中介者模式 | 降低多個對象和類之間的通信復雜性 | 類之間相互引用 | 實體抽象類引用中介抽象接口,實體中介引用所有實體類。實體類中調用中介方法,并傳入特有的標識,實體中介類根據傳進來特有的標識進行不同的處理,可以用策略模式進行搭配 | 減少了原先實體類之間的耦合性 | 實體中介類容易變得臃腫 | ? |
| 16 | 狀態模式 | 允許對象在內部狀態發生改變時改變它的行為,對象看起來好像修改了它的類 | 調用自身方法來改變自身的狀態,又會根據不同的狀態來調用不同的方法。避免if...else顯得臃腫 | 對原先的Context中每個狀態創建一個狀態類,狀態接口類需要實現和Context相同的方法。狀態類中的每個方法返回值都是下一個狀態。Context成員有下一個狀態和狀態接口的引用。Context方法中就是根據下一個狀態來初始化狀態對象,調用狀態對象中的方法并且再獲得下一個狀態。 | 避免Context類臃腫,狀態類可以與單例模式進行配合 | ? | ? |
| 17 | 備忘錄模式 | 存儲原先對象的屬性,又稱之為快照。方便之后回退。即游戲進度的存檔和讀檔 | 需要有回退功能的類 | 可以用內部類的形式表現,成員是原實體中重要的屬性,可以和原型模式搭配 | ? | ? | 現如今,儲存/讀取對象有更方便的方式。備忘錄模式在如今有些過時。更有效的方式可以替代備忘錄模式,例如對象序列化,對象編碼等。 |
| 18 | 組合(整體)模式 | 是用于把一組相似的對象當作一個單一的對象進行統一的處理 | 對不同對象類型的批量處理操作 | 建立一個容器類,成員是實體的抽象數組。并且自身也繼承于抽象類,對于容器來說操作要對抽象數組進行遍歷遞歸調用方法,對于非容器來說,專心實現自己的方法就行。 | ? | ? | 容器相當于根節點,非容器相當于葉子節點。RadioButton,Button,GroupBox的關系一樣,當GroupBox進行disable時,GroupBox包含的RadioButton,Button,GroupBox也一樣要disable |
| 19 | 迭代器模式 | 提供一種方法順序訪問一個集合對象中的各個元素,而又不需要暴露該對象的內部表示。 | 遍歷容器又不向暴露內部 | 迭代器類成員包含實體的引用,可用構造函數初始化。迭代器中實現最基本的first,next,isdone,currentItem方法,實體類中getIterator(){ return MyIterator(*this);} | ? | ? | STL庫中等其他類庫有現成的 |
| 20 | 職責鏈模式 | 為請求創建了一個接收者對象的鏈 | 有連續傳遞請求的需求 | 通常每個接收者都包含對另一個接收者的引用。判斷自身能否接收請求,如果能就處理不能它就會把相同的請求傳給下一個接收者,依此類推 | ? | ? | 例如Winform的單擊請求,你想觸發布局在底層的控件事件時,那么就要設置上層的控件都無法處理單擊請求 |
| 21 | 命令模式 | 把用戶可以觸發的功能當成一個命令 | 方法參數個數,參數的數據類型,返回值可能不統一。用戶卻想要統一的接口 | 創建用戶想要的命令接口,保留原實體的成員變量和getter&setter。 把方法變成類,并繼承和實現命令接口,成員包含原先的輸入參數和返回值,可用構造函數初始化。 創建命令執行類,成員是 List <ICommand*> ,方法是添加ICommand 和遍歷執行ICommand中的方法 | 方法與實體分離,可以被接收者統一處理。 | ? | ? |
| 22 | 訪問器模式 | 改變基類的方法會影響到派生類的實現 | 穩定層次結構,易變的基類方法需求 | 把原來基類和派生類的實現放在訪問器類中,各個派生類成員包含訪問器的引用,用來訪問這些訪問器的操作方法。而訪問器中的操作方法傳入派生類的實體,對派生類的屬性進行操作,返回值用成員變量保存。這樣要變更操作方法只需要變更具體的訪問器,而不需要變更基類和派生類。 | ? | 如果層次結構不穩定,那么使用訪問者模式就得不償失. | ? |
| 23 | 解釋器模式 | 定義一個語言,用戶可以用這語言來執行相應的操作 | ? | 非終結符和終結符的解析。實際的難點是先學會編譯原理 | ? | 解析算法才是難點 | 如正則表達式等 |
?
?
總結
以上是生活随笔為你收集整理的设计模式的理解:对23个设计模式的总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设计模式的理解:解释器模式 Interp
- 下一篇: 操作系统原理: 操作系统概述