本文所有內容均節選自《設計模式就該這樣學》
序言
Design Patterns: Elements of Reusable Object-Oriented Software(以下簡稱《設計模式》),一書由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides合著(Addison-Wesley,1995)。這四位作者常被稱為“四人組(Gang of Four)”,而這本書也就被稱為“四人組(或 GoF)”書。他們首次給我們總結出一套軟體開發可以反覆使用的經驗,幫助我們提高程式碼的可重用性、系統的可維護性等,解決軟體開發中的複雜問題。
設計模式已誕生20多年,其間相繼出版的關於設計模式的經典著作不計其數。如果說GoF的《設計模式》是設計模式領域的“聖經”,那麼之後出版的各種關於設計模式的書籍可稱為“聖經”的“批註版”或者“白話版”。本書正是基於GoF的《設計模式》來編寫的。
《設計模式》總結的是經驗之談,千萬不要死記硬背,生搬硬套。下面來總體預覽一下設計模式的分類和總結,如下表所示。
分 類 | 解 釋 | 舉 例 |
---|---|---|
建立型設計模式(Creational) | 這類設計模式提供了一種在建立物件的同時隱藏建立邏輯的方式,而不是使用新的運算子直接例項化物件,這使得程式在判斷針對某個給定例項需要建立哪些物件時更加靈活 | 工廠方法模式(Factory Method Pattern)、抽象工廠模式(Abstract Factory Pattern)、單例模式(Singleton Pattern)、原型模式(Prototype Pattern)、建造者模式(Builder Pattern) |
結構型設計模式(Structural) | 這類設計模式關注類和物件的組合。繼承的概念被用來組合介面和定義組合物件獲得新功能的方式 | 代理模式(Proxy Pattern)、門面模式(Facade Pattern)、裝飾器模式(Decorator Pattern)、享元模式(Flyweight Pattern)、組合模式(Composite Pattern)、介面卡模式(Adapter Pattern)、橋接模式(Bridge Pattern) |
行為型設計模式(Behavioral) | 這類設計模式特別關注物件之間的通訊 | 模板方法模式(Template Method Pattern)、策略模式(Strategy Pattern)、責任鏈模式(Chain of Responsibility Pattern)、迭代器模式(Iterator Pattern)、命令模式(Command Pattern)、狀態模式(State Pattern)、備忘錄模式(Memento Pattern)、中介者模式(Mediator Pattern)、直譯器模式(Interpreter Pattern)、觀察者模式(Observer Pattern)、訪問者模式(Visitor Pattern) |
本文是我對“聖經”實踐的精華總結,全文內容節選自《設計模式就該這樣學》,這是一本可以真正能夠落地的“設計模式”之書,也是目前唯一一本結合框架原始碼如何落地“設計模式”這個角度來理解設計模式的書。本文也將會結合JDK、Spring、MyBatis、Tomcat、Netty等經典框架原始碼展開對設計模式的分析。當然,本文還會結合我多年的“踩坑填坑”經驗和“教學答疑”經驗,用比“聖經”更深刻、更全面、更通俗、更生動、更有趣、更接地氣的方式並且結合真實業務場景分析每種設計模式的優缺點,治癒“設計模式選擇困難症”。選設計模式就像相親選物件,一旦做好了接受TA缺點的準備,那TA就一定屬於你。所以,本文對於日常開發而言更具有指導意義。
Tom彈架構,只彈乾貨不摻水,本文所有分享內容均從實戰角度出發,不談概念,只談實戰和應用落地
1 各種設計模式使用頻率總結
以下是根據本人的個人經驗,對設計模式使用頻率的總結,不可作為學術依據,僅供大家參考。因為設計模式的選擇還是要依賴具體的業務場景的,每個人接觸的業務領域都不一樣,自然設計模式的選擇也會不一樣。
1.1 建立型設計模式
如下圖所示,建立型設計模式中使用頻率由高到低依次為工廠方法模式、抽象工廠模式、建造者模式、單例模式、原型模式。原型模式一般都有現成的工具類,自己造輪子的情況比較少。
1.2 結構型設計模式
如下圖所示,結構型設計模式中使用頻率由高到低依次為介面卡模式、裝飾器模式、代理模式、門面模式、組合模式、享元模式、橋接模式。其中橋接模式一般都有現成的工具類,自己造輪子的情況比較少。
1.3 行為型設計模式
如下圖所示,行為型設計模式中使用頻率由高到低依次為策略模式、觀察者模式、責任鏈模式、直譯器模式、模板方法模式、迭代器模式、中介者模式、命令模式、訪問者模式、備忘錄模式、狀態模式。其中,觀察者模式、直譯器模式、迭代器模式、中介者模式、命令模式、訪問者模式、備忘錄模式一般都有現成的工具類,自己造輪子的情況比較少。
下面根據本人多年研究設計模式的經驗總結,將壓箱乾貨首次全網釋出。如果本文對您有幫助一定要收藏,也歡迎關注和點贊;如果您有任何建議也可留言評論或私信,您的支援是我堅持創作的動力。關注『 Tom彈架構 』可獲取更多技術乾貨!
2 為什麼一定要學習設計模式
標題 | 備註 |
---|---|
Tom彈架構:為什麼一定要學習設計模式 | 2021/10/29已更新 |
3 七大架構設計原則篇
標題 | 備註 |
---|---|
Tom彈架構:開閉原則(Open-Closed Principle,OCP) | 2021/10/21已更新 |
Tom彈架構:依賴倒置原則(Dependence Inversion Principle,DIP) | 2021/10/22已更新 |
Tom彈架構:單一職責原則(Simple Responsibility Principle,SRP) | 2021/10/23已更新 |
Tom彈架構:介面隔離原則(Interface Segregation Principle,ISP) | 2021/10/24已更新 |
Tom彈架構:迪米特法則(Law of Demeter,LoD) | 2021/10/25已更新 |
Tom彈架構:里氏替換原則(Liskov Substitution Principle,LSP) | 2021/10/26已更新 |
Tom彈架構:合成複用原則(Composite/Aggregate Reuse Principle,CARP) | 2021/10/27已更新 |
目錄僅代表更新計劃,因精力分配原因不一定按順序目錄順序連載,計劃1個月(即2021年11月31日前)連載完畢,請小夥伴們持續關注本文更新,大家可以先關注和收藏本文或者關注『 Tom彈架構 』更新通知,感謝您的支援!
4 建立型設計模式
標題 | 備註 |
---|---|
Tom彈架構:簡單工廠模式(Simple Factory Pattern) >> 徹底說透簡單工廠那些你沒有關注過的細節 | 2021/11/10已更新 |
Tom彈架構:工廠方法模式(Factory Method Pattern)>> 全面通透深入剖析工廠方法模式 | 2021/11/11已更新 |
Tom彈架構:抽象工廠模式(Abstract Factory Pattern)>> 手寫資料庫連線池,讓抽象工廠不再抽象 | 2021/11/12已更新 |
Tom彈架構:單例模式(Singleton Pattern)>> 這9個單例被破壞的事故現場,你遇到過幾個? | 2021/10/26已更新 |
Tom彈架構:原型模式(Prototype Pattern)>> 一文讀懂深克隆與淺克隆的關係 | 2021/11/02已更新 |
Tom彈架構:建造者模式(Builder Pattern)>> 用建造者模式實現一個防SQL隱碼攻擊的ORM框架 | 2021/10/26已更新 |
5 結構型設計模式
標題 | 備註 |
---|---|
Tom彈架構:代理模式(Proxy Pattern)>> 從沒有人將代理模式分析得如此透徹 | 2021/10/27已更新 |
Tom彈架構:門面模式(Facade Pattern)>> 原來你不知道自己每天都在用門面模式 | 2021/11/13已更新 |
Tom彈架構:裝飾器模式(Decorator Pattern)>> 趣談裝飾器模式,讓你一輩子不會忘 | 2021/11/01已更新 |
Tom彈架構:享元模式(Flyweight Pattern)>> 就因為把int改成Integer,第2天被辭了 | 2021/11/01已更新 |
Tom彈架構:組合模式(Composite Pattern)>> 沒有效能瓶頸的無限級選單樹應該這樣設計 | 2021/11/04已更新 |
Tom彈架構:介面卡模式(Adapter Pattern)>> 如何快速搞定第三方登入且易擴充套件? | 2021/11/03已更新 |
Tom彈架構:橋接模式(Bridge Pattern)>> 使用橋接模式設計複雜的訊息系統 | 2011/11/08已更新 |
6 行為型設計模式
標題 | 備註 |
---|---|
Tom彈架構:委派模式(Delegate Pattern)>> 你以為委派模式很神祕,其實你每天都在用 | 2021/11/09已更新 |
Tom彈架構:模板方法模式(Template Method Pattern)>> 搞懂鉤子方法和模板方法,看完這篇就夠了 | 2021/11/07已更新 |
Tom彈架構:策略模式(Strategy Pattern)>> 使用策略模式重構電商折扣和支付場景 | 2021/11/05已更新 |
Tom彈架構:責任鏈模式(Chain of Responsibility Pattern)>> 這才是責任鏈模式的優雅使用方式 | 2021/10/27已更新 |
Tom彈架構:迭代器模式(Iterator Pattern)>> 手寫自定義迭代器,秒懂迭代器底層原理 | 2021/11/15已更新 |
Tom彈架構:命令模式(Command Pattern)>> 使用命令模式重構播放器控制條 | 2021/11/22已更新 |
Tom彈架構:狀態模式(State Pattern)>> 徹底搞懂Spring狀態機原理,實現訂單與物流解耦 | 2021/11/16已更新 |
Tom彈架構:備忘錄模式(Memento Pattern)>> 100行程式碼,輕鬆搞定文字編輯器中草稿箱 | 2021/11/23已更新 |
Tom彈架構:中介者模式(Mediator Pattern)>> 微信和QQ這麼多群,該如何管理好友關係? | 2021/11/23已更新 |
Tom彈架構:直譯器模式(Interpreter Pattern)>> 這個無敵設計,可以解析並運算任意數學表示式 | 2021/11/18已更新 |
Tom彈架構:觀察者模式(Observer Pattern)>> 基於Guava API實現非同步通知和事件回撥 | 2021/11/17已更新 |
Tom彈架構:訪問者模式(Visitor Pattern) | 2021/11/24已更新 |
7 新設計模式
標題 | 備註 |
---|---|
Tom彈架構:物件池模式(Object Pool Pattern) | 2021/11/25已更新 |
Tom彈架構:規格模式(Specification Pattern) | 2021/11/25已更新 |
Tom彈架構:空物件模式(Null Object Pattern) | 2021/11/25已更新 |
Tom彈架構:僱工模式(Employee Pattern) | 2021/11/25已更新 |
8 一句話歸納設計模式
各種設計模式對比及程式設計思想總結如下表所示。
設計模式 | 一句話歸納 | 目 的 | 生活案例 | 框架原始碼舉例 |
---|---|---|---|---|
工廠模式(Factory Pattern) | 產品標準化, 生產更高效 |
封裝建立細節 | 實體工廠 | LoggerFactory、Calender |
單例模式(Singleton Pattern) | 世上只有一個我 | 保證獨一無二 | CEO | BeanFactory、Runtime |
原型模式(Prototype Pattern) | 拔一根猴毛, 吹出千萬個 |
高效建立物件 | 克隆 | ArrayList、PrototypeBean |
建造者模式(Builder Pattern) | 高配中配與低配, 想選哪配就哪配 |
開放個性配置步驟 | 選配 | StringBuilder、 BeanDefinitionBuilder |
代理模式(Proxy Pattern) | 沒有資源沒時間, 得找媒婆來幫忙 |
增強職責 | 媒婆 | ProxyFactoryBean、 JdkDynamicAopProxy、CglibAopProxy |
門面模式(Facade Pattern) | 開啟一扇門, 通向全世界 |
統一訪問入口 | 前臺 | JdbcUtils、RequestFacade |
裝飾器模式(Decorator Pattern) | 他大舅他二舅, 都是他舅 |
靈活擴充套件、 同宗同源 |
煎餅 | BufferedReader、InputStream |
享元模式(Flyweight Pattern) | 優化資源配置, 減少重複浪費 |
共享資源池 | 全國社保聯網 | String、Integer、ObjectPool |
組合模式(Composite Pattern) | 人在一起叫團伙, 心在一起叫團隊 |
統一整體和個體 | 組織架構樹 | HashMap、SqlNode |
介面卡模式(Adapter Pattern) | 萬能充電器 | 相容轉換 電源適配 | AdvisorAdapter、HandlerAdapter | |
橋接模式(Bridge Pattern) | 約定優於配置 | 不允許用繼承 | 橋 | DriverManager |
委派模式(Delegate Pattern) | 這個需求很簡單, 怎麼實現我不管 |
只對結果負責 | 授權委託書 | ClassLoader、 BeanDefinitionParserDelegate |
模板模式(Template Pattern) | 流程全部標準化, 需要微調請覆蓋 |
邏輯複用 | 把大象裝進冰箱 | JdbcTemplate、HttpServlet |
策略模式(Strategy Pattern) | 條條大道通北京, 具體哪條你來定 |
把選擇權交給使用者 | 選擇支付方式 | Comparator、 InstantiationStrategy |
責任鏈模式(Chain of Responsibility Pattern) | 各人自掃門前雪, 莫管他人瓦上霜 |
解耦處理邏輯 | 踢皮球 | FilterChain、Pipeline |
迭代器模式(Iterator Pattern) | 流水線上坐一天, 每個包裹掃一遍 |
統一對集合的訪問方式 | 逐個檢票進站 | Iterator |
命令模式(Command Pattern) | 運籌帷幄之中, 決勝千里之外 |
解耦請求和處理 | 遙控器 | Runnable、TestCase |
狀態模式(State Pattern) | 狀態驅動行為, 行為決定狀態 |
繫結狀態和行為 | 訂單狀態跟蹤 | Lifecycle |
備忘錄模式(Memento Pattern) | 失足不成千古恨, 想重來時就重來 |
備份,後悔機制 | 草稿箱 | StateManageableMessageContext |
中介者模式(Mediator Pattern) | 聯絡方式我給你, 怎麼搞定我不管 |
統一管理網狀資源 | 朋友圈 | Timer |
直譯器模式(Interpreter Pattern) | 我想說“方言”, 一切解釋權歸我 |
實現特定語法解析 | 摩斯密碼 | Pattern、ExpressionParser |
觀察者模式(Observer Pattern) | 到點就通知我 | 解耦觀察者與被觀察者 | 鬧鐘 | ContextLoaderListener |
訪問者模式(Visitor Pattern) | 橫看成嶺側成峰, 遠近高低各不同 |
解耦資料結構和資料操作 | KPI考核 | FileVisitor、BeanDefinitionVisitor |
不管是面試也好,還是日常開發也好,相信大家都已經胸有成竹、信心滿滿了。但是從筆者的架構經驗和教學經驗總結來看,還有很多小夥伴對一些設計模式經常混淆難懂。以下內容將是我對設計模式的最精華總結,收集了我在教學過程中很多來自學員的疑問,對各種容易混淆的設計模式進行比較,並總結整理了以下內容,希望幫助大家在以後的設計選型中能夠披荊斬棘,如履平地。如果你在閱讀本書之前,對設計模式較為熟悉,本章內容可以幫助你鞏固加深理解。
9 建立型設計模式對比
9.1 工廠方法模式與抽象工廠模式對比
對比 | 說明 |
---|---|
共同點 | 1. 都屬於建立型設計模式。 2. 職責相同 |
不同點 | 所建立產品的擴充套件程度不同:工廠方法模式只能單向維度擴充套件產品;而抽象工廠模式可以讓產品等級結構和產品族的相互擴充套件,而且可以多維度擴充套件(至少是二維擴充套件) |
關聯性 | 抽象工廠很多時候不一定是介面,而是抽象類;工廠方法類一般作為抽象工廠類的子類 |
類圖對比 | |
類圖解釋 | 從類圖上看,抽象工廠模式中的抽象產品可以是多個維度的,而工廠方法模式中的抽象產品是單維度的。因此抽象工廠模式中的產品可以支援多維度擴充套件,而工廠方法模式中的產品只能單維度擴充套件。一個抽象工廠可以建立同一產品族下的多個抽象產品,而工廠方法模式並沒有引入產品族的概念,只要是抽象產品的實現類都可以建立 |
9.2 簡單工廠模式與單例模式對比
對比 | 說明 |
---|---|
共同點 | 1.都屬於建立型設計模式。 2.都會提供對外的獲取物件的方法 |
不同點 | 職責不同:單例模式的職責是確保一個類在Java虛擬機器裡只有一個物件,整個系統共享這個物件;簡單工廠模式的職責是封裝物件的建立細節 |
關聯性 | 在實際業務程式碼中,通常把工廠類設計為單例物件 |
類圖對比 | |
類圖解釋 | 從類圖上看,單例模式和簡單工廠模式並沒有直接的關聯 |
9.3 簡單工廠模式與建造者模式對比
對比 | 說明 |
---|---|
共同點 | 1. 都屬於建立型設計模式。 2. 職責相同,都是將建立產品的細節封裝起來 |
不同點 | 1. 目的不同:簡單工廠模式關注建立一個完整的標準產品,而建造者模式更關注建立個性化的產品。 2. 產品的複雜度不同:簡單工廠模式建立的一般都是單一性質的產品,建造者模式可以建立複合型產品。一般來說,簡單工廠模式建立的產品物件粒度比較粗,建造者模式建立的產品物件粒度更細 |
關聯性 | 在實際業務程式碼中,通常把工廠類設計為單例物件 |
類圖對比 | |
類圖解釋 | 從類圖上看,建造者模式比簡單工廠模式多了一個建造者類。對於客戶端而言,使用者在呼叫build()方法之前都只是對產品引數的預設。而在簡單工廠模式中,沒有預設引數的動作,直接呼叫建立產品的方法獲取產品的例項 |
10 結構型設計模式對比
10.1 裝飾器模式與代理模式對比
對比 | 說明 |
---|---|
共同點 | 1. 都屬於結構型設計模式。 2. 都是包裝器模式的實現。 3. 都是為了達到功能增強的目的 |
不同點 | 1. 實現形式不同:代理模式通過組合實現功能增強和擴充套件,裝飾器模式通過繼承實現增強和擴充套件。 2. 目的不同:代理模式著重代理的過程控制,而裝飾器模式則是對類功能的加強或減弱,更注重類功能的變化。 3. 可擴充套件程度不同:裝飾器模式的程式碼擴充套件靈活度更大,代理模式的擴充套件相對來說依賴性更強 |
關聯性 | 裝飾器模式可以說是靜態代理模式的一個特殊應用 |
類圖對比 | |
類圖解釋 | 從類圖上看,裝飾器模式中會設計一個抽象的元件,後面不管是裝飾器還是具體的元件,都是抽象元件的實現類,屬於同一繼承體系,功能擴充套件是在具體的裝飾器中完成的。而代理模式用的是硬編碼,功能的擴充套件簡單粗暴 |
10.2 裝飾器模式與門面模式對比
對比 | 說明 |
---|---|
共同點 | 1.都屬於建立型設計模式。 2.都是包裝器模式的實現 |
不同點 | 目的不同:裝飾器模式的主要目的是統一多個子系統的訪問入口,承擔一定的靜態代理作用,大部分時候也會用到委派模式。裝飾器模式的主要目的是功能擴充套件,而且擴充套件的類與目標類一定是同宗同源的 |
關聯性 | 從程式碼結構上看,二者都是包裝器模式的一種實現,二者也都會用到靜態代理 |
類圖對比 | |
類圖解釋 | 從類圖上看,門面模式中的門面類更像是一個萬能的類,看上去涵蓋了所有子系統的功能。而裝飾器模式更符合單一職責原則 |
10.3 裝飾器模式與介面卡模式對比
對比 | 說明 |
---|---|
共同點 | 1. 都屬於結構型設計模式。 2. 都是包裝器模式的實現 |
不同點 | 1. 程式碼結構不同:裝飾器模式包裝的都是自己的兄弟類,同宗同源;而介面卡模式則是將一個非本家族的物件偽裝起來。 2. 設計目的不同:介面卡模式的意義是將一個介面轉變成另一個介面,通過改變介面來達到重複使用的目的;而裝飾器模式不是要改變被裝飾物件的介面,而是恰恰要保持原有的介面,但是增強原有物件的功能,或者改變原有物件的處理方式,從而提升效能 |
關聯性 | 裝飾器模式和介面卡模式只有結構上容易混淆,在具體業務場景中還是很容易區分的 |
類圖對比 | |
類圖解釋 | 從類圖上看,沒有太多的相似點。裝飾器模式多了一個抽象裝飾者,便於子類擴充套件。而介面卡模式沒有抽象裝飾者這一層,直接擴充套件介面 |
10.4 介面卡模式與代理模式對比
對比 | 說明 |
---|---|
共同點 | 1. 都屬於結構型設計模式。 2. 都是包裝器模式的實現。 3. 二者都起到了隱藏和保護原類的作用 |
不同點 | 目的不同:介面卡模式主要解決相容問題,會保留被適配物件已經存在的方法並繼續對外開放呼叫;而代理模式主要是為了功能增強,目標類的方法不會直接提供給使用者呼叫,而是呼叫代理類的方法獲得增強後的結果 |
關聯性 | 物件介面卡就是靜態代理的一種實現 |
類圖對比 | |
類圖解釋 | 從類圖來看,代理模式中的目標類和代理類繼承同一父類,而介面卡模式中只有介面卡類才繼承目標介面 |
11 行為型設計模式對比
11.1 策略模式與模板方法模式對比
對比 | 說明 |
---|---|
共同點 | 1. 都屬於行為型設計模式。 2. 都可以用來分離高層的演算法和低層的具體實現細節,允許高層的演算法獨立於它的具體實現細節重用 |
不同點 | 1. 開放程度不同:策略模式允許外界呼叫其介面方法,而模板方法模式則限制介面方法只能在子類呼叫。 2. 方法控制權不同:模板方法模式採用繼承的方式實現演算法的異構,其關鍵點就是將演算法封裝在抽象基類中,並將不同的演算法實現細節放在子類中實現,控制權在使用者。而模板方法模式符合依賴倒置原則,父類呼叫子類的操作,底層模組實現高層模組宣告的介面。這樣控制權在父類,底層模組要依賴高層模組 |
關聯性 | 有時候會混合使用,模板方法模式中可能設計的鉤子方法,就是某一個策略的實現 |
類圖對比 | |
類圖解釋 | 從類圖來看,在策略模式中的策略類,是實現策略抽象介面的全部方法。而在模板方法模式中,具體的實現類只實現模板類的部分方法,模板類通常為抽象類,而非介面 |
11.2 策略模式與命令模式對比
對比 | 說明 |
---|---|
共同點 | 1. 都屬於行為型設計模式。 2. 都需要對外提供一個功能清單給使用者選擇 |
不同點 | 業務場景不同:當不使用命令模式時,請求和處理的程式碼是寫在一起的,但通常會降低呼叫者的體驗,因此命令模式通常用於解耦請求和處理的場景。使用命令模式一般會有一個回撥,反饋和處理結果。而策略模式則是封裝演算法,提供固定好的選項,讓使用者參與到業務的執行過程中,選擇不同的策略最終會得到同一型別的結果。因為每一種策略都是可以相互替換的 |
關聯性 | 命令模式內部的有些邏輯處理可以設計成策略模式 |
類圖對比 | |
類圖解釋 | 從類圖來看,一個命令在形式上很像一種策略。只是命令模式多了一個接收者角色。但是在命令模式中,每條命令都是不能相互替換的,而在策略模式中,每種策略都是可以相互替換的 |
11.3 策略模式與委派模式對比
對比 | 說明 |
---|---|
共同點 | 都屬於行為型設計模式 |
不同點 | 關注點不同:策略模式關注策略是否能相互替代,而委派模式更關注分發和排程的過程 |
關聯性 | 委派模式內部通常會用到策略切換的上下文容器 |
類圖對比 | |
類圖解釋 | 從類圖上看,策略模式中上下文容器只是演算法策略的選擇切換所在,不需要實現策略介面。委派模式中委派者和被委派者實現了同一個介面 |
11.4 橋接模式與介面卡模式對比
對比 | 說明 |
---|---|
共同點 | 1. 都屬於行為型設計模式。 2. 程式碼組織結構類似:介面卡模式和橋接模式都是間接引用物件,因此可以使系統更靈活,在實現上都涉及從自身以外的一個介面向被引用的物件發出請求 |
不同點 | 1. 適用場景不同:介面卡模式主要解決已有介面間的相容問題,被適配的介面實現像是一個黑匣子,我們不想也不能修改這個介面及其實現,也不可能控制其演化,只要相關的物件能與系統定義的介面協同工作即可。介面卡模式經常被用在與第三方產品的功能整合上,採用介面卡模式適應新型別的增加的方式是開發針對這個型別的介面卡。橋接模式則不同,參與橋接的介面是穩定的,使用者可以擴充套件和修改橋接中的類,但是不能改變介面。 2. 設計原則不同:橋接模式不使用繼承建立聯絡。而介面卡模式中類介面卡寫法用的繼承,物件介面卡寫法用的組合,介面介面卡寫法實際上用的也是繼承,與橋接模式有由根本區別 |
關聯性 | 按照GoF的說法,橋接模式和介面卡模式用於設計的不同階段,橋接模式用於設計的前期,即在設計類時將類規劃為邏輯和實現兩個大類,是它們可以分別精心演化的;而介面卡模式用於設計完成之後,當發現設計完成的類無法協同工作時,可以採用介面卡模式。然而很多情況下在設計初期就要考慮介面卡模式的使用,如涉及大量第三方應用介面的情況 |
類圖對比 | |
類圖解釋 | 從類圖上看,橋接模式比介面卡模式更復雜,實際上多了一個橋接角色 |
11.5 橋接模式與組合模式對比
對比 | 說明 |
---|---|
共同點 | 都屬於行為型設計模式 |
不同點 | 目的不同:橋接模式的目的是將兩個繼承體系建立連線,是為了滿足個性的需求的。而組合模式的目的不是建立連線,而是統一行動,統一成同一套API便於整體操作 |
關聯性 | 橋接模式和組合模式關聯性不大 |
類圖對比 | |
類圖解釋 | 從類圖上看,橋接模式相對組合模式而言,其類圖要複雜得多。橋接模式中抽象和實現不使用繼承。而在組合模式中,所有的節點都具有共同的抽象,只有這樣才能夠統一操作 |
12 跨類綜合對比
12.1 享元模式與容器式單例模式對比
對比 | 說明 |
---|---|
共同點 | 1. 都設計了一個快取物件的容器。 2. 設計目的有相似之處,兩者都是為了節省記憶體開銷 |
不同點 | 1. 型別不同:享元模式屬於結構型設計模式,容器式單例模式屬於建立型設計模式。 2. 對建立物件的控制粒度不同:享元模式可以再次建立物件,也可以取快取物件。而單例模式則嚴格控制應用程式中只有一個例項物件。 3. 實現形式不同:享元模式可以通過自己實現對外部的單例,也可以在需要的時候建立更多的物件;單例模式是自身控制,需要增加不屬於該物件本身的邏輯 |
關聯性 | 享元模式可以看成是單例模式的擴充套件,可以把物件池的容器設定為單例。同時,把物件池所在的類設定為單例的工廠。 享元模式 = 單例模式 + 工廠模式 + 組合模式 |
類圖對比 | |
類圖解釋 | 從類圖上看,享元模式的類圖比單例模式要複雜,但是都提供了一個獲取物件的方法 |
12.2 建造者模式與裝飾器模式對比
對比 | 說明 |
---|---|
共同點 | 都有擴充套件裝飾的作用 |
不同點 | 1.型別不同:建造者模式屬於建立型設計模式,裝飾器模式屬於結構型設計模式。 2.應用場景不同:建造者模式針對構建複雜物件,且構建過程不穩定,強調物件建立步驟的個性化,一般來說會有標配;而裝飾器模式針對建造過程十分穩定的情況,採用大桶套小桶 |
關聯性 | 二者很少會出現混合使用的情況 |
類圖對比 | |
類圖解釋 | 從類圖上看,並沒有太多的相似點 |
12.3 策略模式與簡單工廠模式對比
對比 | 說明 |
---|---|
共同點 | 客戶端呼叫方式相同:兩者都是通過傳入引數進行配置的。 |
不同點 | 1.型別不同:策略模式屬於行為型設計模式,簡單工廠模式屬於建立型設計模式。 2.側重點不同:簡單工廠模式則是通過傳參選擇建立出需要的物件,而策略模式則是通過傳參配置出需要的行為演算法。一個是物件建立,另一個是行為演算法的替換。 3.設計邏輯不同:兩者的差別很微妙,簡單工廠模式是直接建立具體的物件並用該物件去執行相應的動作。而策略模式設計一個上下文(Context)類,將操作給了上下文類,策略類內部沒有建立具體的物件,從而實現程式碼的進一步封裝,客戶端程式碼並不需要知道具體的實現過程 |
關聯性 | 一般來說,二者會組合使用,具體策略將由工廠來建立 |
類圖對比 | |
類圖解釋 | 從類圖上看,策略模式和簡單工廠模式非常相似,都通過多型來實現不同子類的選取,這種思想應該是從程式的整體看出來的 |
12.4 策略模式與介面卡模式對比
對比 | 說明 |
---|---|
共同點 | 都是通過找到已經存在的、執行良好的類來實現介面的 |
不同點 | 1. 型別不同:策略模式屬於行為型設計模式,介面卡模式屬於結構型設計模式。 2. 目的不同:策略模式把一系列演算法封裝起來,提供一個統一的介面給客戶,並使這些演算法可以相互間替換;而介面卡模式將一個類的介面轉換成客戶希望的另外一個介面,從而使原本因介面不相容不能一起工作的類可以一起工作。 3. 客戶單端呼叫方式不同:策略模式的所有策略都需要暴露出去,由客戶端決定使用哪一種策略。而介面卡模式是定義好介面的實現方式及內部需要引用的類,客戶端直接呼叫介面卡的方法 |
關聯性 | 策略模式很多時候都和介面卡模式結合使用,把具體介面卡作為具體策略,使用者選擇不同策略從而呼叫不同的介面卡方法 |
類圖對比 | |
類圖解釋 | 從類圖上看,策略模式中方法的形參為介面物件,實參為介面的實現類。而介面卡模式中在介面卡中定義適配者來輔助實現介面 |
12.5 中介者模式與介面卡模式對比
對比 | 說明 |
---|---|
共同點 | 二者本質上都是一樣的,在一個類中呼叫另一個類中的方法,從而減少耦合 |
不同點 | 1.型別不同:中介者模式屬於行為型設計模式,介面卡模式屬於結構型設計模式。 2.目的不同:中介者模式主要完成資源協調,而介面卡模式主要解決相容問題。 3.程式碼結構不同:中介者模式一定是用組合的形式實現程式碼複用的,所有人可能都持有中介者的引用:而介面卡模式可以用繼承的方式實現,也可以用組合的方式來實現程式碼複用 |
關聯性 | 二者並沒有明顯的關聯性 |
類圖對比 | |
類圖解釋 | 從類圖上看,介面卡採用的是物件介面卡的類圖,適配者和被適配者是組合複用的關係。中介者模式中具體的同事類都是持有中介者的引用。適配者和中介者都實現了一個介面(抽象) |
12.6 中介者模式與代理模式對比
對比 | 說明 |
---|---|
共同點 | 都具備保護目標物件的特性 |
不同點 | 1. 型別不同:中介者模式屬於行為型設計模式,代理模式屬於結構型設計模式。 2. 干預程度不同:如果說代理模式是“媒婆”,那麼中介者模式就是“不負責任的媒婆”。 3. 職責不同:代理模式的職責是功能增強,不僅要將目標物件和代理物件建立聯絡,代理物件還要參與過程。而中介者模式中的中介者只負責牽線搭橋,建立聯絡,不參與具體的過程 |
關聯性 | 中介者模式是一種面向更加複雜的物件關係的全權靜態代理(委託) |
類圖對比 | |
類圖解釋 | 從類圖上看,Proxy類和Mediator都具備中介的功能,可以達到保護目標類的作用 |
12.7 中介者模式與橋接模式對比
對比 | 說明 |
---|---|
共同點 | 都具備將兩個物件建立聯絡的特性 |
不同點 | 1.型別不同:中介者模式屬於行為型設計模式,橋接模式屬於結構型設計模式。 2.適用場景不同:橋接模式只適用於將兩個維度建立連線;而中介者模式可以將多個維度建立連線 |
關聯性 | 中介者模式是一種更為複雜的橋接模式,中介者可以和網狀結構的物件建立連線,而橋接模式只能和兩個維度的物件建立連線 |
類圖對比 | |
類圖解釋 | 從類圖上看,中介者模式和橋接模式還是非常相似的,只是中介者模式中採用的是組合複用,而橋接模式中採用的是繼承複用。可以說中介者模式是橋接模式的升級版 |
12.8 橋接模式與命令模式對比
對比 | 說明 |
---|---|
共同點 | 都是為了達到解耦的目的 |
不同點 | 1.型別不同:橋接模式屬於結構型設計模式,命令模式屬於行為型設計模式。 2.目的不同:橋接模式需要一箇中間的實現類,以達到抽象和具體之間解耦的目的。而命令模式需要一個抽象的中間類,只是為了規範,達到請求和處理解耦的目的 |
關聯性 | 橋接模式和命令模式組合使用的場景不常見 |
類圖對比 | |
類圖解釋 | 從類圖上看,橋接模式通過抽象角色來與抽象維度和具體維度建立連線,而命令模式通過封裝命令物件,將呼叫者角色和接收者角色建立連線,二者分別適用於不同的業務場景 |
12.9 委派模式與門面模式對比
對比 | 說明 |
---|---|
共同點 | 從程式碼結構上看,都是包裝器模式,也是一種靜態代理,都具有包裝物件的特性 |
不同點 | 1.型別不同:委派模式屬於行為型設計模式,門面模式屬於結構型設計模式。 2.側重點不同:委派模式針對行為上的統一排程和分發,而門面模式是針對組織結構上的統一入口 |
關聯性 | 在門面模式中,可能會用到委派模式實現任務分發 |
類圖對比 | |
類圖解釋 | 從類圖上看,委派模式和門面模式非常相似,只是在委派模式中多了一個介面,而門面模式沒有一個公共的介面 |
12.10 委派模式與代理模式對比
對比 | 說明 |
---|---|
共同點 | 都有保護目標物件的特性 |
不同點 | 1.型別不同:委派模式屬於行為型設計模式,代理模式屬於結構型設計模式。 2.職責不同:委派模式雖然結構上是一種全權的靜態代理,但對目標類的功能不做任何的增強;而代理模式中的代理類一定會對目標類進行功能增強 |
關聯性 | 委派模式就是全權的靜態代理,不做任何的程式碼增強 |
類圖對比 | |
類圖解釋 | 從類圖上看,委派模式和代理模式幾乎一致。只是委派模式是一個類代理多個目標類,而代理模式是一個類只代理一個目標類 |
在《設計模式就該這樣學》一書中,還有大量的UML圖及易混淆的設計模式對比案例分析,也歡迎大家關注。
在日常應用中,設計模式從來都不是單個設計模式獨立使用的。在實際應用中,通常多個設計模式混合使用,你中有我,我中有你。下圖完整地描述了設計模式之間的混用關係,希望對大家有所幫助。
大家可以先關注和收藏本文,感謝您的支援! 關注微信公眾號『 Tom彈架構 』回覆“設計模式”可獲取完整原始碼。
本文為“Tom彈架構”原創,轉載請註明出處。技術在於分享,我分享我快樂!
如果本文對您有幫助,歡迎關注和點贊;如果您有任何建議也可留言評論或私信,您的支援是我堅持創作的動力。關注微信公眾號『 Tom彈架構 』可獲取更多技術乾貨!