【設計模式】結構型模式——七種
介面卡模式
介面卡(adapter)模式,將一個類的介面轉換成客戶希望的另外一個介面。介面卡模式使得原來由於介面不相容而不能一起工作的那些類可以一起工作。介面卡模式有類的介面卡模式和物件的介面卡模式兩種形式。1、為什麼會出現介面卡模式?
在實際的開發過程中,由於應用環境的變化(如使用開發語言的變化),需要實現在新的環境中沒有現存物件可以滿足,但是其他環境卻存在這樣現存的物件。為了將現存物件在新的環境中進行呼叫,由此產生了介面卡模式。使得新環境中不需要重複實現已經存在了的實現而很好的把現有物件(指原來環境中的現有物件)加入到新環境中來使用。
2、優點
- 可以在不修改原有程式碼的基礎上來複用現有類,符合“開閉原則”。
- 可以重新定義adapter(被適配的類)的部分行為,因為在類介面卡模式中,adapter是adaptee的子類
- 僅僅引入一個物件,並不需要額外的欄位來引用adaptee例項
3、缺點
- 用一個具體的adapter類對adaptee和target進行匹配,當如果想要匹配一個類以及他的子類時,類的介面卡模式就不能勝任了。因為類的介面卡模式中沒有引入adaptee的例項,光呼叫this.specificRequest方法並不能去呼叫他對應子類的specificRequest方法。
- 採用了“多繼承”的實現方式,帶來了不良的高耦合。
橋接模式
1、定義
橋接模式即將抽象部分與實現部分脫耦,使得他們獨立變化互不影響到對方。
2、目的
橋接的目的是使得抽象化與實現化部分分離,根據面向物件的封裝變化的原則,我們可以把實現部分的變化封裝到另一個類中。
3、優點
- 把抽象介面與其實現解耦
- 抽象和實現可以獨立擴充套件,不會影響到對方
- 實現細節對客戶透明,對用於隱藏了具體實現細節
4、缺點
增加了系統的複雜度
裝飾模式
裝飾者模式以對客戶透明的方式動態地給一個物件附加更多的責任,裝飾者模式相比生成子類可以更靈活的增加功能。
裝飾者模式採用物件組合而非繼承的方式實現了再執行時動態的擴充套件物件功能的能力,而且可以根據需要擴充套件多個功能,避免了單獨使用繼承帶來的“靈活性差”和“多子類衍生問題”。同時它很好的符合面向物件設計原則中的“優先使用物件組合而非繼承”和“開發封閉原則”。
1、優點
- 裝飾者模式和繼承的目的都是擴充套件物件的功能,但是裝飾者模式比繼承更靈活
- 通過使用不同的具體裝飾類以及這些類的排列組合,設計師可以創造出很多不同行為的組合
- 裝飾者模式有很好的可擴充套件性
2、缺點
裝飾者模式會導致設計中出現許多小物件,如果過度使用,會讓程式變得更復雜,並且更多的物件會使得差錯變得困難,特別是這些物件看上去都很像。
3、何時使用裝飾者模式?
- 需要擴充套件一個類的功能或給一個類增加附加責任
- 需要動態的給一個物件增加功能,這些功能可以再動態的撤銷
- 需要增加由一個基本功能的排列組合而產生的非常大量的功能
組合模式
組合模式允許將物件組合成樹形結構來表現“部分——整體”的層次結構,使得客戶以一致的方式處理單個物件以及物件的組合。
組合模式實現的最關鍵的地方是:簡單物件和複合物件必須實現相同的介面。這就是組合模式能夠將組合物件和簡單物件進行一致處理的原因。
1、優點
- 組合模式使得客戶端程式碼可以一致的處理物件和物件容器,無需處理單個物件或者組合的物件容器
- 將客戶端程式碼與複雜的物件容器結構解耦
- 可以更容易的往組合物件中加入新的構件
2、缺點
使得設計更為複雜,客戶端需要更多時間來理清類之間的層次關係。
3、何時使用組合模式?
當需求中是體現部分與整體層次結構時,以及希望使用者可以忽略組合物件與單個物件的不同,統一的使用組合結構中的所有物件時,這時應該考慮使用組合模式。
外觀模式
外觀模式為子系統中的一組介面提供一個一致的介面,此模式定義了一個高層介面,這個介面使得這一子系統更加容易使用。
外觀模式提供了一個統一的介面,用來訪問子系統中的一群介面。外觀定義了一個高層介面,讓子系統更容易使用,使用外觀模式時,我們建立了一個統一的類,用來包裝子系統中一個或多個複雜的類,客戶端可以直接通過外觀類來呼叫內部子系統中的方法,從而外觀模式讓客戶和子系統之間避免了耦合。
1、為什麼會出現外觀模式?
在軟體開發過程中,客戶端程式經常會與複雜系統的內部子系統進行耦合,從而導致客戶端程式隨著子系統的變化而變化,然而為了將複雜系統的內部子系統與客戶端之間的依賴解耦,從而產生了外觀模式。
2、外觀模式與介面卡模式的區別
介面卡模式是將一個物件包裝起來以改變其介面,而外觀模式是將一群物件“包裝”起來以簡化其介面。他們的意圖是不一樣的,介面卡模式是將介面轉換為不同介面,而外觀模式是提供一個統一的介面來簡化介面。
3、優點
- 外觀模式對客戶遮蔽了子系統元件,從而簡化了介面,減少了客戶處理的物件數目並使子系統的使用更加簡單
- 外觀模式實現了子系統與客戶之間的鬆耦合關係,而子系統內部的功能元件是緊耦合的,鬆耦合使得子系統的元件變化不會影響到他的客戶
- 外觀模式可以解決層結構分離,降低系統耦合度和為新舊系統互動提供介面的功能。
4、缺點
如果增加新的子系統可能需要修改外觀類或客戶端的原始碼,就違背了“開發——封閉的原則”
5、解決的問題
享元模式主要用來解決由於大量的細粒度物件所造成的記憶體開銷的問題,他在實際的開發過程中並不常用,可以作為底層的提升效能的一種手段。
享元模式
享元模式是指運用共享及時有效的支援大量細粒度的物件。
1、何時使用享元模式?
享元模式可以避免大量非常相似類的開銷,在軟體開發中如果需要生成大量細粒度的類例項來表示資料,如果這些例項除了幾個引數外基本都是相同的,這時候就可以使用享元模式來大幅度減少需要例項化類的數量。
如果能把這些引數(指這些類例項的不同引數)移動類例項外面,在方法呼叫時將他們傳遞進來,這樣就可以通過共享大幅度的減少單個例項的數目。(把類例項外面的引數稱為享元物件的外部狀態,把在享元物件內部定義稱為內部狀態)
內部狀態:在享元物件的內部並且不會隨著環境的改變而改變的共享部分
外部狀態:隨環境改變而改變的,不可以共享的狀態
2、優點
降低了系統中物件的數量,從而降低了系統中細粒度物件給記憶體帶來的壓力
3、缺點
- 為了使物件可以共享,需要將一些狀態外部化,這將使得程式的邏輯更加複雜,使系統複雜化
- 享元模式將享元物件的狀態外部化,而讀取外部狀態使得執行時間稍微變長。
代理模式
代理模式就是給某個物件提供一個代理,並由代理物件控制對原物件的引用。在一些情況下,一個客戶不想或者不能直接引用一個物件,而代理物件可以在客戶端和目標物件之間起到中介的作用。1、為什麼會出現代理模式?
在軟體開發過程中,有些物件有時候會由於網路或其他的障礙,以至於不能夠或者直接訪問到這些物件,如果直接訪問物件給系統帶來不必要的複雜性,這時候可以在客戶端和目標物件之間增加一層中間層,讓代理物件代替目標物件,然後客戶端只需要訪問代理物件,由代理物件去幫我們去請求目標物件並返回結果給客戶端。
2、優點
- 代理模式能夠將呼叫用於真正被呼叫的物件隔離,在一定程度上降低了系統的耦合度
- 代理物件在客戶端和目標物件之間起到一箇中介的作用,這樣可以起到對目標物件的保護,代理物件可以在對目標物件發出請求之前進行一個額外的操作,例如許可權檢查
3、缺點
- 由於在客戶端和真實主題之間增加了一個代理物件,所以對造成請求的處理速度變慢
- 實現代理類也需要增加額外的工作,從而增加了系統的實現複雜度