結構型設計模式對比 設計模式(十六)

来源:https://www.cnblogs.com/noteless/archive/2018/12/07/10080950.html
-Advertisement-
Play Games

結構型設計模式藉助於組合或者繼承以整體結構的形式提供更強大的功能,他們之間有很多點非常相似,本文對七個結構型設計模式進行了對比,代理模式,裝飾器模式,享元模式,橋接模式,外觀模式,組合模式,適配器模式他們之間的異同點,差異點進行了分析,有助於更好地理解學習各種模式。 ...


結構型設計模式 結構型模式關註於整體最終的結構,通過繼承和組合,構建出更加複雜的結構 進而提供更加強大的邏輯功能 七種結構型模式
  • 適配器模式(Adapter Pattern)
  • 組合模式(Composite Pattern)
  • 裝飾器模式(Decorator Pattern)
  • 代理模式(Proxy Pattern) 
  • 橋接模式(Bridge Pattern)
  • 外觀模式(Facade Pattern)
  • 享元模式(Flyweight Pattern)
所有的結構型設計模式在邏輯上都各自不同程度的隱含了“間接”“代理”“委托”的含義 ,有的明顯,有的含蓄  image_5c09c064_5021   強表現 適配器、裝飾器、代理、組合、橋接模式,這幾種模式比較強烈的表現了“間接”“代理”“委托”的含義  從圖中可以清楚地看得出來,他們都有“代理”的含義
適配器模式,通過繼承或者組合方式,“代理”了,被適配角色Adaptee
裝飾器模式,通過組合的方式,"是你還有你",內部擁有Component,代理了被裝飾的具體構建 ConcreteComponent
代理模式,通過組合的方式,內部擁有RealSubject,代理了真實主題角色
組合模式,通過組合的方式,內部包含葉子節點或者樹枝節點,內部“代理”了 子對象
橋接模式,通過組合的方式,內部擁有Implementor,指向實現者
  如果裝飾器模式只有一個被裝飾的類ConcreteComponent,也只有一個裝飾器角色ConcreteDecorator 省略掉Decorator ,他跟代理模式的結構可以說是一樣的 省略掉裝飾器模式結構圖中的ConcreteDecorator角色,組合模式和裝飾器模式的結構就完全一樣了 如果只有一種類型的ConcreteImplementor,橋接模式又與對象適配器模式相同   雖然說他們都有“代理”的含義,但是他們又有很大差別
適配器模式下,“代理”的對象是功能相近的替代方案,比如,插座適配器可以進行插頭轉換
使得原本不相容,不能夠一起工作的那些類能夠一起工作
代理模式下,“代理”的真實主題的對象RealSubject,從而對真實對象進行隱藏,封裝 透明的對外界提供服務,控制外界對這個對象的訪問
裝飾器模式下,“代理”的是抽象的Component構建,能夠代理所有的ConcreteComponent類型
裝飾器和被裝飾的構建都是Component,重點在於功能的擴展,添加額外的職責
組合模式下,“代理”的是抽象構建Component,代理的是子對象,用於描述“整體-部分”的概念
橋接模式,“代理”的是實現角色Implementor,代理的是具體的實現,用於將抽象與實現進行分離
分離後通過橋接模式進行連接
他們雖然都是“代理”,但是他們的側重點不同,被代理的事物的性質不同 適配器模式在代理的過程中,重點在於適配,不會增加額外的功能 代理模式側重於控制,當然也通常用於增加功能 如果代理模式,代理的不是真實主題對象RealSubject,而是抽象構建Subject,顯然,就演化成了裝飾器模式 因為代理模式不光能夠控制外界對真實對象的訪問,他也能夠提供額外的服務 裝飾器模式則是重點在於功能的擴展,增肌額外的職責 而組合模式,重點在於形成“整體--部分”的結構,並且對外界客戶端程式,提供一致的訪問形式   弱表現 享元模式和外觀模式也是一定程度的代理 享元模式,通過內部狀態與外部狀態的分離,通過享元池中的享元對象,代理了所有的具有內外狀態完整的對象 對客戶端來說就是有如此多的對象, 只不過記憶體中卻僅有少量的對象   外觀模式在結構上完全看不出來“代理”的含義,但是他在業務邏輯上充當的也恰恰是“介面人”“協調者”“控制台”的角色 所以也可以認為是“代理”了內部的子系統   代理模式與適配器模式 代理模式和適配器模式都需要藉助於內部的“被代理”對象,或者“被適配者”對象進行工作 也就是說他們都將自己的工作委托出去   但是代理模式中,代理者與被代理者他們擁有相同的介面,也就是擁有相同的對外呈現,重點在於對真實對象的隱藏,客戶端請求的透傳,並且可以額外的增加一些控制,管理 適配器模式中,目標對象和被適配者在介面上沒有必然聯繫,比如目標是港版插座面板,被適配者是大陸插座面板,他們的共同點是提供電力,但是介面卻完全不同 適配器的重點在於不能一起工作的類能夠一起工作   代理模式與裝飾器模式 代理模式提供與被代理的真實對象相同的訪問介面,對真實對象進行一定的控制,也可以增加額外的服務,職責 裝飾器模式也是代理了內部真實的對象,並且擁有相同的訪問介面   但是代理模式重點在於增加對真實對象的控制,隱藏真實對象,一般會在代理類內部創建一個真實的對象 也就是說這種代理關係在編譯時期已經靜態確定了 代理類接受處理來自客戶端的請求,在內部轉發到真實主題對象上 比如
//代理模式
public class Proxy implements Subject{
private Subject realSubject;
public Proxy(){
//關係在編譯時確定
realSubject = new RealSubject();
}
public void doSth(){
….
realSubject.doSth();
….
}
}
裝飾器模式在於功能的動態增加,所以對象一般作為參數進行傳遞,比如:       InputStream inputStream = new BufferedInputStream(new FileInputStream("........")); 這是一種在運行期間動態增加功能方式   適配器與外觀模式 適配器模式將一種介面轉換為另外一種介面,使得原本不能一起工作的類可以協作 外觀模式是將子系統的的多個介面的訪問轉換為另一種介面,使得原本複雜難用,耦合程度高的多個類有一個一致簡單的介面 他們都變成了另外一種形式的介面 所有的請求也都是委托他人進行處理,適配器模式委托給被適配角色,外觀模式委托給子系統   適配器模式是為了能夠一起工作,他們原本是並不相容的 外觀模式是為了能夠更好地更簡單的工作,他們原本是可以一起工作的   橋接模式與適配器模式 適配器模式的主要目的是讓因為介面不相容而不能互相工作的類能夠一起工作 換句話說就是他們本身不同,我用“紐帶” Adapter將他們連接起來
橋接模式則是將原本或許緊密結合在一起的抽象與實現,進行分離 使她們能夠各自獨立的發展,是把連接在一起的兩個事物,拆分開來 然後用“紐帶”“橋梁”(也就是對象的引用)將他們連接起來
適配器模式就好比張三和王五不認識,李四介紹他們認識 橋梁模式好比張三和王五成天黏在一起活幹得不好太亂套,李四說以後我作為介面人,你倆各乾各的吧 雖然看起來都是兩個人幹活,中間一個聯繫人,但是含義卻是完全不同
橋接模式與裝飾器模式 裝飾器模式中,使用組合而不是繼承來對類的功能進行擴展 避免了類的個數的爆炸增長,與橋梁模式的結果不約而同 他們都解決了類爆炸增長的問題,都避免了過多的沒必要的子類
裝飾器模式側重於功能的動態增加,將額外的功能提取到子類中 通過不同的排列組合,形成一個遞歸的調用方式,以動態的增加各部分的功能
橋梁模式是將原本系統中的實現細節抽取出來,比如原來抽象概念與實例化全部都是一個類層次結構中 把所有的實現細節,比如示例中的平臺相關實現,抽取出來,進行分離達到抽象與實現分離的目的
所以雖然他們都可以解決子類爆炸式增長、不易擴展的問題 但是他們的出發點完全不同 一個關註於功能的動態擴展組合 一個關註於抽象與實現的分離,獲得更多的靈活性     總結 所有的結構型模式的都離不開“分離,解耦”的概念 而“分離,解耦”之後,又通過某種形式建立聯繫,比如“組合” 抽象與實現進行分離,分離就意味著獨立,獨立就意味著可以單獨發展,橋接模式 對於分離的事物通過委托的形式托付工作,就可以在中間提供更多的服務,代理模式 而分離的兩個事物也可以通過一定形式的結合、轉換進而一起協同工作,適配器模式 將一個對象的多個功能點進行分離,從而能夠動態的組合以形成更強大的功能,裝飾器模式 將事物自身內部核心狀態與外部狀態進行分離,進而減少核心狀態的存儲運行消耗,享元模式 將客戶端與子系統的耦合交互進行分離,抽象出來一個新的接入點,外觀Facade,降低耦合,外觀模式 分離開的多種事物,如果他們有“整體--部分”的關係,可以將它們組合在一起,形成更複雜的整體結構,組合模式 (ps:上面的分離指分開的,不耦合在一起,不是特指原本是一個整體,被分成兩部分)   以上各個部分的差異對比點主要根據設計模式的最初意圖、動機,設計模式本就是設計原則的實現化角色 對於任何的結構,你都可以按照你自己的想法去使用、拓展,當然,前提是更合適或者更優秀 否則您那是瞎用 比如代理模式與裝飾器模式本就很類似,如果你將代理模式的真實對象也是作為參數進行傳遞 也是用來動態的增加職責,那麼就成了裝飾器模式,所以再回頭,你說你的是代理模式還是裝飾器模式? 這麼看這個名字代理還是裝飾器又有什麼大的區別的呢?都只是用來敘述而已 但是如果你這麼做還非要說是代理模式,有一個很大的問題就是和同事、領導溝通起來就特別費勁了,說不定還會吵起來... 所以,除非你有更好更合適的選擇,或者改變 否則,一定要儘量按照模式原本的意圖和動機去使用某種模式   原文地址:結構型設計模式對比 設計模式(十六)
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • #我的VUE框架學習 題記:初識VUE,覺得VUE十分的不錯,故決定去深入的瞭解學習它,工欲善其事,必先利其器,下麵是我搭建vue環境的過程! #一.項目搭建及初始化 1.安裝:node.js;去官網下載:https://nodejs.org/en/ 2.安裝cnp:mnpm install -g ...
  • 1.語法: var expression = /pattern/flags ; pattern: 任何簡單或複雜的正則表達式。 flags: 可以是 g,i,m 或它們的組合。 g:表示全局模式,即模式將被應用於所有字元串,而非在發現第一個匹配項時就立即停止。 i:表示不區分大小寫。 m:表示多行, ...
  • Chrome下調用play後抱錯:DOMException: play() failed because the user didn't interact with the document first. 聲音無法自動播放這個在IOS/Android上面一直是個慣例,桌面版的Safari在2017年 ...
  • 這篇文章主要為大家詳細介紹了vue文件樹組件的使用方法,具有一定的參考價值,對此有需要的朋友可以參考學習下。如有不足之處,歡迎批評指正。 首先是html模板: 接下來是組件部分的源碼: 所以設計思路就是通過判斷對象是否有子節點來決定是文件夾還是文件,然後通過遞歸復用<item>組件來展示文件樹的效果 ...
  • 本文由雲+社區發表 這段時間有幸加入了一個關於微信小程式的項目開發組,從無到有的根據文檔自行學習了小程式的開發過程,前面已經有幾位前輩的文章珠玉在前,我這裡就先從前端界面的開發方面談一談小程式以及我所遇到的問題吧。 在結構和樣式方面,小程式提供了一些常用的標簽與控制項,比如: view,小程式主要的布 ...
  • 這篇文章主要為大家詳細介紹了vue全局組件與局部組件的使用方法,具有一定的參考價值,對此有需要的朋友可以參考學習下。如有不足之處,歡迎批評指正。 vue全局/局部註冊,以及一些混淆的組件main.js入口文件的一些常用配置, 在入口文件上定義的public.vue為全局組件,在這裡用的是pug模版 ...
  • 計算屬性就是模板內的表達式非常便利,但是設計它們的初衷是用於簡單運算的。 一、什麼是計算屬性 模板內的表達式非常便利,但是設計它們的初衷是用於簡單運算的。在模板中放入太多的邏輯會讓模板過重且難以維護。例如: 這裡的表達式包含3個操作,並不是很清晰,所以遇到複雜邏輯時應該使用Vue特帶的計算屬性com ...
  • element ui源碼的版本是2.4.9 pagination.js pager.vue ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...