摘要:橋接模式和裝飾模式的區別設計模式裝飾模式橋接模式和裝飾模式都是通過將繼承關系轉換為關聯關系從而減少系統中類的數量,降低系統的耦合性。裝飾器模式支持多層裝飾,通過不同的組合可以實現不同的行為。
產生橋接模式的動機:
假設這樣一種情況:
我們有大中小型號的毛筆,有紅藍黑三種顏料。如果需要不同顏色,不同型號的毛筆有如下兩種設計方法:
為每一種型號的毛筆都提供三種顏料的版本。
將毛筆和顏料分開,使用的時候自由組合。
針對第一種我們當下就需要紅色顏料大號毛筆、藍色顏料大號毛筆等九中型號,在之后的擴展中,每增加一個型號的毛筆就需要為其增加所有顏料的版本, 而每增加一種顏料也需要為所有的筆增添新的顏料類型。隨著筆的類型和顏料種類的不斷增長,其類數量的增加速度為O(n!) 我們需要維護龐大的種類集合。
而第二種我們將筆和顏料分開,就比如說準備大中小三種型號的毛筆,以及紅藍黑三種顏料,用的時候就拿筆區蘸一下顏料就可以,這樣筆和顏料解耦,他們可以分開增加。其類的增加速度為O(n) 我們可以看出 O(n!)的增長速度遠大于O(n)。
第一種方法在系統設計上我們采用的就是繼承的方式。實現方式上有兩種,一種就像我上面提到的只有一個抽象類,然后所有子類都是由這個抽象類里面派生出來了,還有一種代碼編寫方式就是提供毛筆抽象類和顏料抽象類 以及他們的派生子類,然后子類使用多繼承分別繼承他們,這種編寫方式又一個問題就是在不支持多繼承的語言中無法實現(例子請看我的 文章中的那一部分。)
第二種方法是采用組合關系的設計,其設計中也是將顏料和筆這兩個變化分開,及分別由筆的抽象類派生出各種各樣的筆和由顏料抽象類派生出的各種各樣的顏料。但是將他們之間連接在一起的是關聯關系方式(不懂的可以區我的這一篇文章看一下)。在結構型設計模式中大量使用這種關聯關系來代替繼承關系以實現解耦,為什么關聯關系可以解耦呢?我認為主要有以下幾點:
繼承關系中,父類的修改會傳播到子類中,容易造成子類的不穩定。
繼承關系在代碼編寫階段已經固定,但是使用關聯關系,我們可以將他們之間的關系確定推遲到程序運行時,更加方便用戶控制。比如使用配置文件來確定關聯關系中的兩個類的類型。
使用關聯關系也可以減少代碼的編寫量,尤其是在變化的種類很多以及后期增加種類的時候。
使用關聯關系在后期增加變化種類,不需要更改已經存在的類。滿足開閉原則
使用關聯關系也將功能分割,符合單一職責原則
橋接模式的定義:橋接模式(Bridge Pattern):將抽象部分與它的實現部分分離,使它們都可以獨立地變化。它是一種對象結構型模式,又稱為柄體(Handle and Body)模式或接口(Interface)模式。
實現 使用繼承方式的實現 UML類圖 python 代碼class BrushAbstraction(object): def __init__(self, size, color): self.paint = None self.__size = size self.__color = color def draw(self): print("Use {} {} brush draw".format(self.__color, self.__size)) class BigBrushAbstration(BrushAbstraction): def __init__(self, color): super(BigBrushAbstration, self).__init__("Big", color) class MiddleBrushAbstration(BrushAbstraction): def __init__(self, color): super(MiddleBrushAbstration, self).__init__("Middle", color) class SmallBrushAbstration(BrushAbstraction): def __init__(self, color): super(SmallBrushAbstration, self).__init__("Small", color) class RedBigBrushAbstration(BigBrushAbstration): def __init__(self): super(RedBigBrushAbstration, self).__init__("Red") class BlueBigBrushAbstration(BigBrushAbstration): def __init__(self): super(BlueBigBrushAbstration, self).__init__("Blue") class BlackBigBrushAbstration(BigBrushAbstration): def __init__(self): super(BlackBigBrushAbstration, self).__init__("Black") class RedMiddleBrushAbstration(MiddleBrushAbstration): def __init__(self): super(RedMiddleBrushAbstration, self).__init__("Red") class BlueMiddleBrushAbstration(MiddleBrushAbstration): def __init__(self): super(BlueMiddleBrushAbstration, self).__init__("Blue") class BlackMiddleBrushAbstration(MiddleBrushAbstration): def __init__(self): super(BlackMiddleBrushAbstration, self).__init__("Black") class RedSmallBrushAbstration(SmallBrushAbstration): def __init__(self): super(RedSmallBrushAbstration, self).__init__("Red") class BlueSmallBrushAbstration(SmallBrushAbstration): def __init__(self): super(BlueSmallBrushAbstration, self).__init__("Blue") class BlackSmallBrushAbstration(SmallBrushAbstration): def __init__(self): super(BlackSmallBrushAbstration, self).__init__("Black") if __name__ == "__main__": blue_big_brush = BlueBigBrushAbstration() blue_big_brush.draw() black_big_brush = BlackBigBrushAbstration() black_big_brush.draw()使用橋接模式重構后 UML類圖 代碼
class BrushAbstraction(object): def __init__(self, size): self.paint = None self.__size = size def dip_paint(self, paint): self.paint = paint def draw(self): print("Use {} {} brush draw".format(self.paint.color(), self.__size)) class BigBrushAbstration(BrushAbstraction): def __init__(self): super(BigBrushAbstration, self).__init__("Big") class MiddleBrushAbstration(BrushAbstraction): def __init__(self): super(MiddleBrushAbstration, self).__init__("Middle") class SmallBrushAbstration(BrushAbstraction): def __init__(self): super(SmallBrushAbstration, self).__init__("Small") class PaintImplementer(object): def __init__(self, color): self.__color = color def color(self): return self.__color class RedPaintImplementer(PaintImplementer): def __init__(self): super(RedPaintImplementer, self).__init__("Red") class BluePaintImplementer(PaintImplementer): def __init__(self): super(BluePaintImplementer, self).__init__("Blue") class BlackPaintImplementer(PaintImplementer): def __init__(self): super(BlackPaintImplementer, self).__init__("Black") if __name__ == "__main__": big_bursh = BigBrushAbstration() big_bursh.dip_paint(BluePaintImplementer()) big_bursh.draw() big_bursh.dip_paint(BlackPaintImplementer()) big_bursh.draw()代碼分析
在上面的繼承方式的實現中我們采用的是單繼承,在我的python設計模式-裝飾模式采用繼承方式就是多繼承。橋接模式有時類似多繼承方法。不過橋接模式產生了很多不同的小對象而多繼承方案產生了很多不同的小類。但是多繼承方案違背了類的單一職責原則(即一個類只應該有一個變化的原因),其次多繼承關系的確定在編碼階段就已經確定,無法靈活的擴展,還有就是很多語言是不支持多繼承的。
橋接模式的優缺點 優點分離了抽象接口與實現部分
提高系統可擴充性,在兩個緯度中任意擴展,都不需對原系統進行修改。
缺點橋接模式的引入會增加系統的理解與設計難度,由于聚合關聯關系建立在抽象層,要求開發者針對抽象進行設計與編程。 - 橋接模式要求正確識別出系統中兩個獨立變化的維度,因此其使用范圍具有一定的局限性。
適用環境如果一個系統需要在構件的抽象化角色和具體化角色之間增加更多的靈活性,避免在兩個層次之間建立靜態的繼承聯系,通過橋接模式可以使它們在抽象層建立一個關聯關系。
抽象化角色和實現化角色可以以繼承的方式獨立擴展而互不影響,在程序運行時可以動態將一個抽象化子類的對象和一個實現化子類的對象進行組合,即系統需要對抽象化角色和實現化角色進行動態耦合。
一個類存在兩個獨立變化的維度,且這兩個維度都需要進行擴展。
雖然在系統中使用繼承是沒有問題的,但是由于抽象化角色和具體化角色需要獨立變化,設計要求需要獨立管理這兩者。
對于那些不希望使用繼承或因為多層次繼承導致系統類的個數急劇增加的系統,橋接模式尤為適用。
橋接模式和裝飾模式的區別python設計模式-裝飾模式
橋接模式和裝飾模式都是通過將繼承關系轉換為關聯關系從而減少系統中類的數量,降低系統的耦合性。
橋接模式是解決一個系統有多個變化維度的一種設計模式。其難點是如何將其中的抽象化與實現化分離(抽象化是指將一組復雜物體的一個或幾個特征抽取出來形成共用部分,在面向對象的程序設計中就是將對象共同的性質抽取出去而形成類的過程。實現化是指給出抽象化中的具體實現,他是對抽象化的建進一步具體化)。使用關聯關系在運行時設置不同的具體類來讓同一個抽象對象表現出不同的行為。在整個過程中抽象化的類其實是不穩定的,不穩定指我們通過傳入不同的實現類改變了抽象類本身的運行結果。
裝飾器模式是解決如何給一個類動態增加職責的一種設計模式。裝飾器模式通過將一個類中需要動態執行的方法抽取出來形成裝飾類,通過關聯關系來將職責的添加推遲到了程序運行時。如果程序支持反射還可以通過配置文件來靈活更改對象的功能。裝飾器模式支持多層裝飾,通過不同的組合可以實現不同的行為。在整個過程中被裝飾對象是穩定的。因為裝飾模式是在被裝飾對象的前后增加功能,而不是改變被裝飾對象本身的功能。具體的裝飾類和被裝飾類可以獨立變化,用戶根據需要動態的增加裝飾類和被裝飾類,并在調用的時候進行組合,無需更改之前的代碼,符合開閉原則。
從實現上看橋接模式中抽象類只包含一個實現類的引用,實現對實現類的調用。而裝飾模式中抽象裝飾類繼承構件抽類類,并且還包含一個對抽象構建的引用。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/44497.html
摘要:本文只是尋找設計模式在中的應用。來補全這一塊工廠模式中的應用包線程池解釋和代碼線程池中有線程創建工廠。狀態模式中的應用解釋和代碼根據一個指針的狀態而改變自己的行為適配器模式中的應用解釋和代碼將一個類的接口轉換成客戶希望的另外一個接口。 前言 最近重學設計模式,而且還有很多源碼要看。所以就想一舉兩得。從源碼中尋找設計模式。順便還可以看看源碼。。。本文只是尋找設計模式在java中的應用。優...
摘要:這種模式我們稱之為裝飾器模式。因為裝飾器模式是在給對象增加責任。以下情況適合使用裝飾器模式在不影響其他對象的情況下,以動態透明的方式給單個對象添加職責。 前言 本篇的裝飾器模式不是講解的python中的語法糖 @ 這個裝飾器。而是講解設計模式中的裝飾器模式。網上很多的實現都是基于java和c++的。本文則使用python來實現,其中有些實現可能在python并不需要那樣來寫的,但是思路...
摘要:橋接模式屬于結構型模式的一種,用于把抽象化與實現化解耦,使得二者可以獨立變化,它通過提供抽象化和實現化之間的橋接結構,來實現二者的解耦。相關模式裝飾模式與橋接模式在一定程度上都是為了減少子類的數目,避免出現復雜的繼承關系。 橋接模式(Brideg Pattern)屬于結構型模式的一種,用于把抽象化與實現化解耦,使得二者可以獨立變化,它通過提供抽象化和實現化之間的橋接結構,來實現二者的解...
閱讀 2579·2023-04-26 03:00
閱讀 1392·2021-10-12 10:12
閱讀 4190·2021-09-22 15:33
閱讀 2908·2021-09-22 15:06
閱讀 1530·2019-08-30 15:44
閱讀 2145·2019-08-30 13:59
閱讀 534·2019-08-30 11:24
閱讀 2407·2019-08-29 17:07