軟件開發設計模式之【7】個【結構型】設計模式

代碼碼雲倉庫地址:https://gitee.com/dzxmy/design_pattern

常用的結構型設計模式有:適配器模式,裝飾者模式,代理模式,外觀模式,橋接模式,享元模式

不常用的結構型設計模式有:組合模式

一、外觀模式

定義:又叫門面模式,提供了一個統一的接口,用來訪問子系統中的一羣接口,外觀模式定義了一個高層接口,讓子系統更容易使用

類型:結構型 

優點:簡化了調用過程,無需瞭解深入子系統,防止帶來風險,減少系統依賴,鬆散耦合,更好的劃分訪問層次,符合迪米特法則,即最少知道原則

缺點:增加子系統、擴展子系統行爲容易引入風險,不符合開閉原則

com.dzx.design.structural.facade 包下代碼:外觀模式

二、 裝飾者模式

定義:在不改變原有對象的基礎之上,將功能附加到對象上,提供了比繼承更有彈性的替代方案(擴展原有對象功能)

類型:結構型

適用場景:擴展一個類的功能或給一個類添加附加職責,動態的給一個對象添加功能,這些功能可以再動態的撤銷

優點:

  • 繼承的有力補充,比繼承靈活,不改變原有對象的情況下,給對象一個擴展功能
  • 通過使用不同裝飾類以及這些裝飾類的排列組合,可以實現不同效果
  • 符合開閉原則

缺點:

  • 會出現更多的代碼,更多的類,增加程序複雜性
  • 動態裝飾時,多層裝飾時
com.dzx.design.structural.decorator.v2 包下代碼

三 、適配器模式

定義:將一個類的接口轉換成客戶期望的另一個接口 ,使原本接口不兼容的類可以一起工作

類型:結構型

使用場景:已經存在的類,它的方法和需求不匹配時(方法結果相同或類似) 

不是軟件設計階段考慮的設計模式,是隨着軟件維護,由於不同產品,不同廠家造成功能類似而接口不相同情況下的解決方案

優點:

  • 能提高類的透明性和複用,現有的類複用但不需要改變
  • 目標類和適配器類解耦,提高程序擴展性
  • 符合開閉原則

缺點:

  • 適配器編寫過程需要全面考慮,可能會增加系統的複雜性
  • 增加系統代碼的可讀難度
com.dzx.design.structural.adapter 包下代碼:適配器模式

 

四、享元模式

定義:提供了減少對象數量從而改善應用所需的對象的結構的方式

運用共享技術有效地支持 大量細粒度的對象

 類型:結構型

使用場景:常常應用於系統底層的開發,以便解決系統的性能問題,比如java種的String類,和數據庫連接池

系統有大量相似的對象,需要緩衝池的場景。

優點:減少對象的創建,降低內存中對象的數量,降低系統的內存,提高效率,減少內存之外的其他資源佔用 

缺點:關注內外部狀態,關注線程安全問題,使系統,程序的邏輯複雜化

com.dzx.design.structural.flyweight 包下代碼:享元模式

 五、組合模式

定義:將對象組合成樹形結構以表示“部分-整體”的層次結構

組合模式使客戶端對單個對象和組合對象保持一致的方式處理

類型:結構型

適用場景:

  • 希望客戶端可以忽略組合對象與單個對象的差異時
  • 處理一個樹型結構時

優點:清楚的定義分層次的複雜對象,表示對象的全部或部分層次,讓客戶端忽略層次差異,方便對整個層次結構進行控制,簡化客戶端代碼,符合開閉原則。

缺點:限制類型時會較爲複雜,使設計變得更加抽象

com.dzx.design.structural.composite 包下代碼: 組合模式

六、 橋接模式

定義:將抽象部分與它的具體實現部分分離,使他們都可以獨立地變化

通過組合的方式建立兩個類之間聯繫,而不是繼承

類型:結構型

適用場景:

  • 抽象和具體實現之間增加更多的靈活性
  • 一個類存在兩個(或多個)獨立變化的維度,且這兩個(或多個維度都需要獨立進行擴展)
  • 不希望使用繼承,或因爲多層繼承導致系統類的個數劇增

優點:分離抽象部分及其具體實現部分,提高了系統的可擴展性,符合開閉原則,符合合成複用原則

缺點:增加了系統的理解與設計難度,需要正確地識別出系統中兩個獨立變化的維度

com.dzx.design.structural.bridge 包下代碼:橋接模式

 七、代理模式

定義: 爲其他對象提供一種代理,以控制對這個對象的訪問

代理對象在客戶端和目標對象之間起到中介的作用

適用場景:保護目標對象,增強目標對象

類型:結構型

優點:

  • 代理模式能將代理對象與真實被調用的目標對象分離
  • 一定程度上降低了系統的耦合度,擴展性好
  • 保護目標對象,增強目標對象

缺點:

  • 代理模式會造成系統設計中類的數目增加
  • 在客戶端和目標對象增加一個代理對象,會造成請求處理速度變慢
  • 增加系統的複雜度

分爲靜態代理 、 動態代理、CGLib代理

spring的代理選擇

  • 當Bean有實現接口時,spring就會用jdk的動態代理
  • 當Bean沒有實現接口時,spring使用cglib
  • 可以強制使用cglib,在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>

參考資料:https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html

靜態代理編碼:

com.dzx.design.structural.proxy.staticproxy 包下代碼 : 靜態代理模式

動態模式編碼:

com.dzx.design.structural.proxy.dynamicproxy 包下代碼: 動態代理模式(核心:生成代理對象,重寫InvocationHandler的invoke方法)

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章