本文所有內容均節選自《設計模式就該這樣學》
序言
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彈架構 』可獲取更多技術干貨!