設計模式的六大原則 單一職責原則 里氏替換原則 依賴倒置原則 介面隔離原則 迪米特原則 開閉原則 設計模式的分類 創建型模式 創建型模式:對對象實例化的抽象,通過採用抽象類所定義的介面,封裝了系統中對象如何創建,組合等信息。包括以下幾種設計模式 抽象工廠模式 優點 分離了具體類 更容易在產品系列中進 ...
設計模式的六大原則
- 單一職責原則
- 里氏替換原則
- 依賴倒置原則
- 介面隔離原則
- 迪米特原則
- 開閉原則
設計模式的分類
創建型模式
創建型模式:對對象實例化的抽象,通過採用抽象類所定義的介面,封裝了系統中對象如何創建,組合等信息。包括以下幾種設計模式
抽象工廠模式
優點
- 分離了具體類
- 更容易在產品系列中進行轉換
- 提高了產品間一致性
缺點
- 難以支持新的產品等級結構
- 支持新的產品等級結構就要擴展原來的抽象工廠介面
適用場景
- 系統獨立於產品的創建,組成以及表示
- 系統配置成具有多個產品的系列
- 當要強調一系列相關的產品對象的設計便於進行聯合使用時
- 當提供一個產品類庫,而只想顯示它們的介面而不是實現時
應用舉例
在很多軟體系統中需要更換界面主題,要求界面中的按鈕,文本框,背景色等一起發生改變時可以使用抽象工廠模式進行設計
構建器模式
優點
- 產品的內部表象可以獨立變化
- 將構建代碼與表示代碼相分離,可以使客戶端不必知道產品內部組成的細節
缺點
- 構建器模式創建的產品一般具有較多的共同點,其組成部分相似,如果產品之間差異性很大。則不適合使用構建器模式
- 如果產品的內部變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大
適用場景
創建複雜對象的演算法獨立於組成對象的部分以及這些部分的集合方式
構造過程必須允許已構建對象有不同表示
應用舉例
在很多游戲軟體中,地圖包括天空,地面背景等組成部分,人物角色包括人體,服裝,裝備等組成部分,可以使用建造者模式對其進行設計,通過不同的具體建造者創建不同類型的地圖或人物
工廠方法模式
定義一個用於創建對象(產品)的介面,由子類決定實例化那個類的對象( 產品)
優點
- 沒有了將應用程式綁定到代碼中的要求,代碼只處理介面,因此可以使用任何實現了介面的類
- 允許子類提供對象的擴展版本
- 符合迪米特法則,依賴倒置原則,里氏替換原則
缺點
- 需要Creator和相應的子類作為工廠方法的載體,如果應用模型確實需要creator的子類存在,則很好,否則需要增加一個類層次
適用場景
- 當一個類不知道他所創建的產品的具體是那個子類時
- 當創建對象的過程希望延緩到子類中進行時
類希望子類指定他要創建的對象
應用舉例
Windows的COM組件與MFC
原型模式
指定創建對象的種類,並且通過拷貝這些原型創建新的對象,以一個已有的對象作為原型,通過他來創建新對象
優點
- 可以在允許時添加或刪除產品
- 原型模式提供簡化的創建結構
- 具有給一個應用軟體載入新功能的能力
產品類不需要非得由任何實現確定的等級結構
缺點
每一個類必須配備一個克隆方法
適用場景
- 在運行時,指定需要實例化的類,例如動態載入,避免構建與產品的類層次結構相似的共產類層次結構
當類的實例是僅有的一些不同狀態組合
單例模式
一個類只有一個實例
優點
- 對單個實例的受控制訪問
- 名稱空間減少
- 允許改進操作和表示
- 允許可變數目的實例
比類操作更靈活
缺點
單例類的擴展有很大困難,且職責過重,這在一定程度上違背了單一職責原則
適用場景
只有一個類實例
應用舉例
逐漸生成器
結構型模式
主要用於如何組合已有的類和對象以獲得更大的結構,它採用繼承機制組合介面來實現,以提供 統一的外部試圖或新的功能
適配器模式
將一個類的介面轉換成客戶希望的另外一個介面,Adapter模式使得原本的介面不相容而不能一起工作的那些類可以一起工作
優點
- 允許兩個或多個不相容的對象進行交互和通信
- 提高已有功能的重覆適用
- 增加了類的透明度
- 靈活性
缺點
過多的適用適配器會讓系統非常凌亂,不易整體進行把握
適用場景
- 要使用已有的類,而該類介面與所需的介面並不匹配
- 要創建可重覆使用的類,該類可以與不相干或未知類進行協助,即類之間不需要相容介面
- 要在一個不同於已知介面的介面環境重使用對象
- 必須要進行多個源之間的介面轉換的時候
應用舉例
在.Net重有一個類庫已經實現的,非常重要的適配器——Data Adapter
橋接模式
將一個輔助的組件分成兩個獨立的但又相關的繼承層次結構
優點
- 可以將介面與是實現相分離
- 提高可擴展性
對客戶端隱藏了實現細節
缺點
- 增加了系統的理解和設計難度
要求正確的識別出系統重兩個獨立變化的維度,因此其使用範圍有一定的局限性
適用場景
- 想避免在抽象及其實現之間存在永久的綁定
- 抽象及其實現可以使用子類進行擴展
- 抽象的實現被改動應該對客戶端沒有影響
組合模式
將對象組合成樹型結構以表示“部分-整體”的層次結構
優點
- 清楚的定義分層次的複雜對象,表示對象的全部或部分層次
- 使得增加新構件 更容易了了
- 提高了結構的靈活性和可管理的介面
缺點
使設計變得更加抽象。如果對象的業務規則很複雜,則實現組合模式具有很大的挑戰性,而且不是所有的方法都與葉子對象子類有關聯
適用場景
- 想表示對象的部分--整體層次結構
- 希望用戶忽略組合對象與單個對象的不同,用戶將統一的使用組合結構重的所有對象
結構可以具有任何級別的複雜性,而且是動態的
應用舉例
部分、整體場景如樹型菜單,文件,文件夾的管理
裝飾模式
動態的給對象添加一些額外的責任,就增加功能來說,裝飾比生成子類更為靈活
優點
- 比靜態繼承具有更大的靈活性
- 簡化代碼
- 改進對象的擴展性,用戶可以通過編寫新的類來做出改變
- 裝飾類和被裝飾類可以獨立發展,不會相互耦合
缺點
多層裝飾比較複雜
適用場景
- 想要在單個對象動態並且透明的添加責任,而這樣不會影響其他對象
- 想要在以後可能要修改的對象重添加責任
- 當無法通過靜態子類化實現擴展時
外觀模式
為子系統重的一組介面提供一個統一的介面,外觀模式通過一個高層介面隔離了外部系統與子系統間複雜的交互過程,使得複雜系統的子系統更容易使用
優點
- 在不減少系統所提供的選項的情況下,為複雜系統提供了簡單的介面
- 客戶端屏蔽了子系統組件
- 提高了子系統和其客戶端之間的弱耦合度
- 將客戶端請求轉發後能夠處理這些請求的子系統
缺點
- 不能很好的限制客戶使用子系統類,如果對客戶訪問子系統做太多的限制,則減少了可變性和靈活性
- 在不引入抽象外觀類的情況下,增加新的子系統可能需要修改外觀類或客戶端的源代碼,違背了開閉原則
適用場景
- 為一個複雜子系統提供一個簡單介面時
- 客戶程式與抽象類的實現之間存在著很大的依賴性
- 構建一個層次結構的子系統時,適用Facade模式定義子系統中每層的入口點,如果子系統之間是相互依賴的,你可以讓他們僅通過Facade進行通信,從而簡化了他們之間的依賴關係
享元模式
通過共用對象減少系統中低等級的,詳細的對象數目
優點
- 減少了要處理的對象數目
- 如果對象能夠持續,可以減少記憶體和存儲設備
缺點
- 使得應用程式在某種程度上來說更加複雜化了
- 為了使對象可以共用,享元模式需要將享元對象的狀態外部化,而讀取外部狀態使得運行時間變長
適用場景
- 應用程式使用大量的對象
- 由於對象數目巨大,導致很高的存儲開銷
- 應用程式不依賴於對象的身份
代理模式
為控制初始對象的訪問,提供了一個代理或者占位符對象
優點
- 遠程代理可以隱藏對象位於不同的地址空間的事實
虛擬代理可以執行優化操作
缺點
- 請求的處理速度變慢
實現代理模式需要額外的工作,從而增加了系統實現的複雜度
適用場景
- 當需要為了一個對象在不同的地址空間提供局部的代表時
當需要創建開銷非常大的對象時
應用舉例
防火牆代理---保護目標不讓惡意用戶靠近
行為型模型
從大量的實際行動中概括出來作為行為的理論抽象、基本框架和標準,該類模式主要用於對象之間的職責及其提供的服務的分配,他不僅描述對象或類的模式,還描述它們之間的通信模式
責任鏈模式
在系統中建立一個鏈,消息可以首先接收到他的級別被處理,或者定位到可以處理他的對象
優點
- 降低耦合度
- 增加向對象指定責任的靈活性
適用場景
- 多個對象可以處理一個請求,而其處理器卻是未知的
- 可以動態指定能夠處理請求的對象集
命令模式
在對象中封裝請求,保存命令並傳遞給方法以及任何其他對象一樣返回該命令
優點
- 添加新命令不用修改已有類
- 將操作對象與知道如何完成操作的對象相分離
適用場景
- 想要通過要執行的動作來參數化對象
- 在不同的時間指定、排序以及執行請求
解釋器模式
解釋定義其語法表示的語言
優點
- 容易修改並擴展語法
- 容易實現語法
適用場景
- 語言的語法比較簡單
- 效率並不是最主要的問題
迭代器模式
提供一種方法順序的訪問一個聚合對象中的各個元素,而又不暴露改對象的內部表示
優點
- 支持集合的不同遍歷
- 簡化集合介面
適用場景
- 在不開放集合內部對象表示的前提下訪問集合對象內容
- 支持記號個對象的多重遍歷
- 為遍歷集合中的不同結構提供了統一的介面
備忘錄模式
保持對象狀態的“快照”,在不向外界公開其內容的情況下返回到它的最初狀態
優點
- 保持封裝完整
- 簡化了返回到初始狀態所需的操作
適用場景
- 必須保存對象的快照
- 適用直接介面來獲得狀態有可能會公開對象的實現細節,從而破壞對象的封裝性
觀察者模式
為組件向相關接收方廣播消息提供了靈活的方法
優點
- 抽象了主體與Observer 之間的耦合關係
- 支持廣播方式的通信
適用場景
- 對一個對象的修改涉及其他對象的修改,而不知道有多少對象需要修改
- 對象應該能在不設置對象標識的情況下通知其他對象
狀態模式
允許對象在內部狀態變化時變更其行為,並且修改其類
優點
- 定位指定狀態的行為,並根據不同的狀態來劃分行為
適用場景
- 對象行為依賴於其狀態,且對象必須在運行時根據其狀態修改行為
- 操作具有大量以及多部份組成的取決於對象狀態的條件語句
策略模式
定義了一組用來表示可能行為集合的類
優點
- 另一種子類化方法
- 在類自身中定義行為,減少條件語句
- 更容易擴展模型
適用場景
- 許多相關類只是在行文方面有所區別
- 需要演算法的不同變體
- 演算法使用客戶端未知的數據
模板方法模式
提供了在不重寫方法的前提下允許子類重載部分方法的方法
優點
- 代碼使用
適用場景
- 想要一次實現演算法的不變部分,適用子類實現演算法的可變行為
- 子類間通用行為需要分解,定位到通用類,可以避免代碼重覆問題
訪問者模式
提供了一種方便的,可維護的方法來表示在對象結構元素上進行的操作。改模式允許在不改變操作元素的類的前提下定義一個新操作
優點
- 容易添加新操作
集中相關操作並且排除不相關操作
適用場景
- 定義對象結構的類很少被修改,但想要在此結構上定義新的操作
對象結構包含許多具有不同介面的對象類,並且想要對這些依賴於具體的類的對象進行操作
中介者模式
通過引入一個能夠管理對象間消息分佈的對象,簡化系統中對象的通信
優點
- 取出對象間的影響
- 簡化對象間的協議
- 集中化控制
適用場景
- 對象集合需要一個定義但複雜的方式進行通信
- 想要在不使用子類的情況下自定義分佈在幾個對象間的行為
本文由博客一文多發平臺 OpenWrite 發佈!