1. 程式人生 > >【設計模式】——結構型模式

【設計模式】——結構型模式

【介面卡模式】

定義:

介面卡模式(Adapter)將一個類的介面轉換成客戶希望的另外一個介面,Adapter模式使得原本由於介面不相容而不能一起工作的那些類可以一起工作。符合開放——封閉原則。


系統的資料和行為都正確,但是介面不符時,我們應該考慮用介面卡,目的是使控制範圍之外的一個原有物件與某個介面匹配,介面卡模式主要應用於希望複用一些現存的類,但是介面又與複用環境要求不一致。

類別:

物件介面卡模式:介面卡和適配者之間是關聯關係,主要討論

類介面卡模式:介面卡和適配者是繼承關係,但是C#或是其他語言不支援多重繼承

場合:

1.使用一個已經存在的類,但如果它的介面,也就是它的方法和你的要求不相同時

2.雙方都不太容易修改的時候再使用介面卡模式適配

【裝飾模式】

定義:

裝飾模式(Decorator)在不必改變原類檔案情況下,動態地擴充套件一個物件的功能,它是通過建立一個包裝物件,也就是裝飾來包裹真實的物件,就增加功能來說,裝飾模式比生成子類更為靈活。


特點:

1.裝飾物件和真實物件有相同的介面。這樣客戶端物件就能以和真實物件相同的方式和裝飾物件互動。

2.裝飾物件包含一個真實物件的引用。

3.裝飾物件接受所有來自客戶端的請求,它把這些請求轉發給真實的物件。

4.裝飾物件可以在轉發這些請求以前或以後增加一些附加功能。這樣就確保了在執行時,不用修改給定物件的結構就可以在外部增加附加的功能。在面向物件的設計中,通常是通過繼承來實現對給定類的功能擴充套件。

優點:

1.把類中的裝飾功能從類中搬移去除,這樣可以簡化原有的類。

2.有效的把類的核心職責和裝飾功能區分開來,而且可以去除相關類的重複裝飾邏輯。

缺點:

程式的複雜性

【橋接模式】

定義

橋接模式(Bridge),將抽象部分與它的實現部分分離,使它們可以獨立地變化。符合合成/聚合複用原則。


解釋:

抽象部分和它的實現分離,並不是說讓抽象類與其派生類分離,實現指的是抽象類和它的派生類用來實現自己的物件。在軟體系統中,某些型別由於自身的邏輯,它具有兩個或多個維度的變化,那麼如何應對這種"多維度的變化"?這就要使用橋接模式。如手機可以按照品牌分類也可以按照軟體進行分類。

優點:

實現系統可能有多個角度分類,每一個分類都有可能變化,那麼實現這種多角度分離出來讓它們獨立變化,減少它們之間的耦合。

【組合模式】

定義:

組合模式(Composite)將物件組合成樹形結構以表示“部分整體”的層次結構,組合模式使得使用者對單個物件和組合物件的使用具有一致性。


場合:

1.你想表示物件的部分-整體層次結構

2.你希望使用者忽略組合物件與單個物件的不同,使用者將統一地使用組合結構中的所有物件。

【享元模式】

定義:

享元模式(Flyweight)運用共享技術有效地支援大量細粒度的物件。系統只使用少量的物件,而這些物件都很相似,狀態變化很小,可以實現物件的多次複用。由於享元模式要求能夠共享的物件必須是細粒度物件,因此它又稱為輕量級模式,它是一種物件結構型模式。


解釋:

享元模式通過共享技術實現相同或相似物件的重用,在邏輯上每一個出現的字元都有一個物件與之對應,然而在物理上它們卻共享同一個享元物件,這個物件可以出現在一個字串的不同地方,相同的字元物件都指向同一個例項,在享元模式中,儲存這些共享例項物件的地方稱為享元池(Flyweight Pool)。

內部狀態和外部狀態:

內部狀態儲存在享元內部,不會隨環境的改變而有所不同,是可以共享的。

外部狀態是不可以共享的,它隨環境的改變而改變的,因此外蘊狀態是由客戶端來保持。

場合:

1.如果一個應用程式使用了大量的物件,而大量的這些物件造成了很大的儲存開銷時。

2.物件的大多數狀態可以是外部狀態,如果刪除物件的外部狀態,那麼可以用相對較少的共享物件取代很多組物件。

【代理模式】

定義:代理模式(Proxy),為其他物件提供一種代理以控制對這個物件的訪問。


場合:

1.遠端代理:為一個物件在不同的地址空間提供區域性代表,隱藏一個物件存在於不同的地址空間的事實。

2.虛擬代理:根據需要建立開銷很大的物件,通過它來存放例項化需要很長時間的真實物件。

3.安全代理:用來控制真實物件訪問時的許可權。

4.智慧指引:當呼叫真實物件時,代理處理另外一些事。

我的理解

代理代表一個單一物件,它的客戶端無法直接訪問目標物件,由代理提供對子系統的目標物件的訪問。

【外觀模式】

定義

外觀模式(Facade)為子系統中的一組介面提供一個一致的介面,此模式定義了一個高層介面,這一介面使得這一子系統更加容易使用。符合迪米特原則。


場合:

1. 設計初期階段:應該有意識的將不同的兩個層分離。

2.開發階段:子系統往往因不但重構演化而變得越來越複雜,增加外觀Façade可以提供一個簡單的介面,減少它們之間的依賴。

3.維護一個遺留的大型系統時,為新系統提供一個外觀Façade類,來提供設計粗糙或高度複雜度的遺留程式碼的比較清晰的簡單介面。

我的理解:

如果兩個類不必彼此直接通訊,那麼就不要讓這兩個類發生直接的互相作用,而是定義一個新的介面去進行連線,這樣也符合迪米特原則,讓子系統的通訊和互相依賴達到最小。

代理VS外觀

代理物件代表一個單一物件     客戶物件無法訪問目標物件

外觀物件代表一個子系統         客戶物件可以直接訪問各個目標物件

代理VS介面卡

代理是原來物件的代表

介面卡不虛構一個代表者,將原來的類進行特定的組合

外觀VS介面卡

外觀定義一個新的介面    適配整個子系統

介面卡複用原有介面        適配物件