您好,登錄后才能下訂單哦!
結構型模式概述
結構型模式(Structural Pattern)描述如何將類或者對象結合在一起形成更大的結構,就像搭積木,可以通過簡單積木的組合形成復雜的、功能更為強大的結構。
結構型模式概述
結構型模式可以分為類結構型模式和對象結構型模式
類結構型模式關心類的組合,由多個類可以組合成一個更大的系統,在類結構型模式中一般只存在繼承關系和實現關系。
對象結構型模式關心類與對象的組合,通過關聯關系使得在一個類中定義另一個類的實例對象,然后通過該對象調用其方法。根據“合成復用原則”,在系統中盡量使用關聯關系來替代繼承關系,因此大部分結構型模式都是對象結構型模式。
適配器模式(Adapter)
橋接模式(Bridge)
組合模式(Composite)
裝飾模式(Decorator)
外觀模式(Facade)
享元模式(Flyweight)
代理模式(Proxy)
1適配器模式
把客戶類的請求轉化為對適配者的相應接口的調用
1.1 優點
將目標類和適配者類解耦,通過引入一個適配器類來重用現有的適配者類,而無須修改原有代碼。
增加了類的透明性和復用性,將具體的實現封裝在適配者類中,對于客戶端類來說是透明的,而且提高了適配者的復用性。
靈活性和擴展性都非常好,通過使用配置文件,可以很方便地更換適配器,也可以在不修改原有代碼的基礎上增加新的適配器類,完全符合“開閉原則”。
1.2 缺點
類適配器模式還具有如下優點:
由于適配器類是適配者類的子類,因此可以在適配器類中置換一些適配者的方法,使得適配器的靈活性更強。
類適配器模式的缺點如下:
對于Java、C#等不支持多重繼承的語言,一次最多只能適配一個適配者類,而且目標抽象類只能為抽象類,不能為具體類,其使用有一定的局限性,不能將一個適配者類和它的子類都適配到目標接口。
對象適配器模式還具有如下優點:
一個對象適配器可以把多個不同的適配者適配到同一個目標,也就是說,同一個適配器可以把適配者類和它的子類都適配到目標接口。
對象適配器模式的缺點如下:
與類適配器模式相比,要想置換適配者類的方法就不容易。如果一定要置換掉適配者類的一個或多個方法,就只好先做一個適配者類的子類,將適配者類的方法置換掉,然后再把適配者類的子類當做真正的適配者進行適配,實現過程較為復雜。
1.3情景
系統需要使用現有的類,而這些類的接口不符合系統的需要。
想要建立一個可以重復使用的類,用于與一些彼此之間沒有太大關聯的一些類,包括一些可能在將來引進的類一起工作。
1.4類圖
類適配器
對象適配器
Target:目標抽象類
Adapter:適配器類
Adaptee:適配者類
Client:客戶類
2.橋接模式
2.1 動機
橋接模式將繼承關系轉換為關聯關系,從而降低了類與類之間的耦合,減少了代碼編寫量。
2.2 優點
分離抽象接口及其實現部分。橋接模式有時類似于多繼承方案,但是多繼承方案違背了類的單一職責原則(即一個類只有一個變化的原因),復用性比較差,而且多繼承結構中類的個數非常龐大,橋接模式是比多繼承方案更好的解決方法。
橋接模式提高了系統的可擴充性,在兩個變化維度中任意擴展一個維度,都不需要修改原有系統。
實現細節對客戶透明,可以對用戶隱藏實現細節。
2.3缺點
橋接模式的引入會增加系統的理解與設計難度,由于聚合關聯關系建立在抽象層,要求開發者針對抽象進行設計與編程。
橋接模式要求正確識別出系統中兩個獨立變化的維度,因此其使用范圍具有一定的局限性。
2.4 情景
如果一個系統需要在構件的抽象化角色和具體化角色之間增加更多的靈活性,避免在兩個層次之間建立靜態的繼承聯系,通過橋接模式可以使它們在抽象層建立一個關聯關系。
抽象化角色和實現化角色可以以繼承的方式獨立擴展而互不影響,在程序運行時可以動態將一個抽象化子類的對象和一個實現化子類的對象進行組合,即系統需要對抽象化角色和實現化角色進行動態耦合。
一個類存在兩個獨立變化的維度,且這兩個維度都需要進行擴展。
雖然在系統中使用繼承是沒有問題的,但是由于抽象化角色和具體化角色需要獨立變化,設計要求需要獨立管理這兩者。
對于那些不希望使用繼承或因為多層次繼承導致系統類的個數急劇增加的系統,橋接模式尤為適用。
2.5 類圖
Abstraction:抽象類
RefinedAbstraction:擴充抽象類
Implementor:實現類接口
ConcreteImplementor:具體實現類
3.組合模式
3.1 動機
組合模式描述了如何將容器對象和葉子對象進行遞歸組合,使得用戶在使用時無須對它們進行區分,可以一致地對待容器對象和葉子對象,這就是組合模式的模式動機。
3.2 優點
可以清楚地定義分層次的復雜對象,表示對象的全部或部分層次,使得增加新構件也更容易。
客戶端調用簡單,客戶端可以一致的使用組合結構或其中單個對象。
定義了包含葉子對象和容器對象的類層次結構,葉子對象可以被組合成更復雜的容器對象,而這個容器對象又可以被組合,這樣不斷遞歸下去,可以形成復雜的樹形結構。
更容易在組合體內加入對象構件,客戶端不必因為加入了新的對象構件而更改原有代碼。
3.3缺點
使設計變得更加抽象,對象的業務規則如果很復雜,則實現組合模式具有很大挑戰性,而且不是所有的方法都與葉子對象子類都有關聯。
增加新構件時可能會產生一些問題,很難對容器中的構件類型進行限制。
3.4 情景
需要表示一個對象整體或部分層次,在具有整體和部分的層次結構中,希望通過一種方式忽略整體與部分的差異,可以一致地對待它們。
讓客戶能夠忽略不同對象層次的變化,客戶端可以針對抽象構件編程,無須關心對象層次結構的細節。
對象的結構是動態的并且復雜程度不一樣,但客戶需要一致地處理它們。
3.5 類圖
Component: 抽象構件
Leaf: 葉子構件
Composite: 容器構件
Client: 客戶類
4. 裝飾模式
4.1 動機
裝飾模式以對客戶透明的方式動態地給一個對象附加上更多的責任,換言之,客戶端并不會覺得對象在裝飾前和裝飾后有什么不同。裝飾模式可以在不需要創造更多子類的情況下,將對象的功能加以擴展。這就是裝飾模式的模式動機。
4.2 優點
裝飾模式與繼承關系的目的都是要擴展對象的功能,但是裝飾模式可以提供比繼承更多的靈活性。
可以通過一種動態的方式來擴展一個對象的功能,通過配置文件可以在運行時選擇不同的裝飾器,從而實現不同的行為。
通過使用不同的具體裝飾類以及這些裝飾類的排列組合,可以創造出很多不同行為的組合。可以使用多個具體裝飾類來裝飾同一對象,得到功能更為強大的對象。
具體構件類與具體裝飾類可以獨立變化,用戶可以根據需要增加新的具體構件類和具體裝飾類,在使用時再對其進行組合,原有代碼無須改變,符合“開閉原則”。
4.3缺點
使用裝飾模式進行系統設計時將產生很多小對象,這些對象的區別在于它們之間相互連接的方式有所不同,而不是它們的類或者屬性值有所不同,同時還將產生很多具體裝飾類。這些裝飾類和小對象的產生將增加系統的復雜度,加大學習與理解的難度。
這種比繼承更加靈活機動的特性,也同時意味著裝飾模式比繼承更加易于出錯,排錯也很困難,對于多次裝飾的對象,調試時尋找錯誤可能需要逐級排查,較為煩瑣。
4.4情景
在不影響其他對象的情況下,以動態、透明的方式給單個對象添加職責。
需要動態地給一個對象增加功能,這些功能也可以動態地被撤銷。
當不能采用繼承的方式對系統進行擴充或者采用繼承不利于系統擴展和維護時。不能采用繼承的情況主要有兩類:第一類是系統中存在大量獨立的擴展,為支持每一種組合將產生大量的子類,使得子類數目呈爆炸性增長;第二類是因為類定義不能繼承(如final類)。
4.5類圖
Component: 抽象構件
ConcreteComponent: 具體構件
Decorator: 抽象裝飾類
ConcreteDecorator: 具體裝飾類
5. 外觀模式
5.1 動機
引入外觀角色之后,用戶只需要直接與外觀角色交互,用戶與子系統之間的復雜關系由外觀角色來實現,從而降低了系統的耦合度。
5.2 優點
對客戶屏蔽子系統組件,減少了客戶處理的對象數目并使得子系統使用起來更加容易。通過引入外觀模式,客戶代碼將變得很簡單,與之關聯的對象也很少。
實現了子系統與客戶之間的松耦合關系,這使得子系統的組件變化不會影響到調用它的客戶類,只需要調整外觀類即可。
降低了大型軟件系統中的編譯依賴性,并簡化了系統在不同平臺之間的移植過程,因為編譯一個子系統一般不需要編譯所有其他的子系統。一個子系統的修改對其他子系統沒有任何影響,而且子系統內部變化也不會影響到外觀對象。
只是提供了一個訪問子系統的統一入口,并不影響用戶直接使用子系統類。
5.3缺點
不能很好地限制客戶使用子系統類,如果對客戶訪問子系統類做太多的限制則減少了可變性和靈活性。
在不引入抽象外觀類的情況下,增加新的子系統可能需要修改外觀類或客戶端的源代碼,違背了“開閉原則”。
5.4情景
當要為一個復雜子系統提供一個簡單接口時可以使用外觀模式。該接口可以滿足大多數用戶的需求,而且用戶也可以越過外觀類直接訪問子系統。
客戶程序與多個子系統之間存在很大的依賴性。引入外觀類將子系統與客戶以及其他子系統解耦,可以提高子系統的獨立性和可移植性。
在層次化結構中,可以使用外觀模式定義系統中每一層的入口,層與層之間不直接產生聯系,而通過外觀類建立聯系,降低層之間的耦合度。
5.5類圖
Facade: 外觀角色
SubSystem:子系統角色
6. 享元模式
6.1 動機
在享元模式中共享的是享元對象的內部狀態,外部狀態需要通過環境來設置。在實際使用中,能夠共享的內部狀態是有限的,因此享元對象一般都設計為較小的對象,它所包含的內部狀態較少,這種對象也稱為細粒度對象。享元模式的目的就是使用共享技術來實現大量細粒度對象的復用。
6.2 優點
享元模式的優點在于它可以極大減少內存中對象的數量,使得相同對象或相似對象在內存中只保存一份。
享元模式的外部狀態相對獨立,而且不會影響其內部狀態,從而使得享元對象可以在不同的環境中被共享。
6.3缺點
享元模式使得系統更加復雜,需要分離出內部狀態和外部狀態,這使得程序的邏輯復雜化。
為了使對象可以共享,享元模式需要將享元對象的狀態外部化,而讀取外部狀態使得運行時間變長。
6.4情景
一個系統有大量相同或者相似的對象,由于這類對象的大量使用,造成內存的大量耗費。
對象的大部分狀態都可以外部化,可以將這些外部狀態傳入對象中。
使用享元模式需要維護一個存儲享元對象的享元池,而這需要耗費資源,因此,應當在多次重復使用享元對象時才值得使用享元模式。
6.5類圖
Flyweight: 抽象享元類
ConcreteFlyweight: 具體享元類
UnsharedConcreteFlyweight: 非共享具體享元類
FlyweightFactory: 享元工廠類
7.代理模式
7.1 動機
通過引入一個新的對象(如小圖片和遠程代理對象)來實現對真實對象的操作或者將新的對象作為真實對象的一個替身,這種實現機制即為代理模式,通過引入代理對象來間接訪問一個對象,這就是代理模式的模式動機。
7.2 優點
代理模式能夠協調調用者和被調用者,在一定程度上降低了系統的耦合度。
遠程代理使得客戶端可以訪問在遠程機器上的對象,遠程機器可能具有更好的計算性能與處理速度,可以快速響應并處理客戶端請求。
虛擬代理通過使用一個小對象來代表一個大對象,可以減少系統資源的消耗,對系統進行優化并提高運行速度。
保護代理可以控制對真實對象的使用權限。
7.3缺點
由于在客戶端和真實主題之間增加了代理對象,因此有些類型的代理模式可能會造成請求的處理速度變慢。
實現代理模式需要額外的工作,有些代理模式的實現非常復雜。
7.4情景
根據代理模式的使用目的,常見的代理模式有以下幾種類型:
遠程(Remote)代理:為一個位于不同的地址空間的對象提供一個本地的代理對象,這個不同的地址空間可以是在同一臺主機中,也可是在另一臺主機中,遠程代理又叫做大使(Ambassador)。
虛擬(Virtual)代理:如果需要創建一個資源消耗較大的對象,先創建一個消耗相對較小的對象來表示,真實對象只在需要時才會被真正創建。
Copy-on-Write代理:它是虛擬代理的一種,把復制(克隆)操作延遲到只有在客戶端真正需要時才執行。一般來說,對象的深克隆是一個開銷較大的操作,Copy-on-Write代理可以讓這個操作延遲,只有對象被用到的時候才被克隆。
根據代理模式的使用目的,代理模式有以下幾種類型(續):
保護(Protect or Access)代理:控制對一個對象的訪問,可以給不同的用戶提供不同級別的使用權限。
緩沖(Cache)代理:為某一個目標操作的結果提供臨時的存儲空間,以便多個客戶端可以共享這些結果。
防火墻(Firewall)代理:保護目標不讓惡意用戶接近。
同步化(Synchronization)代理:使幾個用戶能夠同時使用一個對象而沒有沖突。
智能引用(Smart Reference)代理:當一個對象被引用時,提供一些額外的操作,如將此對象被調用的次數記錄下來等。
7.5類圖
Subject: 抽象主題角色
Proxy: 代理主題角色
RealSubject: 真實主題角色
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。