假設這樣一種狀況:
咱們有大中小型號的毛筆,有紅藍黑三種顏料。若是須要不一樣顏色,不一樣型號的毛筆有以下兩種設計方法:python
針對第一種咱們當下就須要紅色顏料大號毛筆、藍色顏料大號毛筆等九中型號,在以後的擴展中,每增長一個型號的毛筆就須要爲其增長全部顏料的版本, 而每增長一種顏料也須要爲全部的筆增添新的顏料類型。隨着筆的類型和顏料種類的不斷增加,其類數量的增長速度爲O(n!) 咱們須要維護龐大的種類集合。
而第二種咱們將筆和顏料分開,就好比說準備大中小三種型號的毛筆,以及紅藍黑三種顏料,用的時候就拿筆區蘸一下顏料就能夠,這樣筆和顏料解耦,他們能夠分開增長。其類的增長速度爲O(n) 咱們能夠看出 O(n!)的增加速度遠大於O(n)。編程
第一種方法在系統設計上咱們採用的就是繼承的方式。實現方式上有兩種,一種就像我上面提到的只有一個抽象類,而後全部子類都是由這個抽象類裏面派生出來了,還有一種代碼編寫方式就是提供毛筆抽象類和顏料抽象類 以及他們的派生子類,而後子類使用多繼承分別繼承他們,這種編寫方式又一個問題就是在不支持多繼承的語言中沒法實現(例子請看個人 文章中的那一部分。)segmentfault
第二種方法是採用組合關係的設計,其設計中也是將顏料和筆這兩個變化分開,及分別由筆的抽象類派生出各類各樣的筆和由顏料抽象類派生出的各類各樣的顏料。可是將他們之間鏈接在一塊兒的是關聯關係方式(不懂的能夠區個人這一篇文章看一下)。在結構型設計模式中大量使用這種關聯關係來代替繼承關係以實現解耦,爲何關聯關係能夠解耦呢?我認爲主要有如下幾點:設計模式
橋接模式(Bridge Pattern):將抽象部分與它的實現部分分離,使它們均可以獨立地變化。它是一種對象結構型模式,又稱爲柄體(Handle and Body)模式或接口(Interface)模式。編碼
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()
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設計模式-裝飾模式採用繼承方式就是多繼承。橋接模式有時相似多繼承方法。不過橋接模式產生了不少不一樣的小對象而多繼承方案產生了不少不一樣的小類。可是多繼承方案違背了類的單一職責原則(即一個類只應該有一個變化的緣由),其次多繼承關係的肯定在編碼階段就已經肯定,沒法靈活的擴展,還有就是不少語言是不支持多繼承的。spa
橋接模式的引入會增長系統的理解與設計難度,因爲聚合關聯關係創建在抽象層,要求開發者針對抽象進行設計與編程。 - 橋接模式要求正確識別出系統中兩個獨立變化的維度,所以其使用範圍具備必定的侷限性。設計
python設計模式-裝飾模式code