用於將“抽象”(比如接口或算法)與實現方式相分離
若干基類
每個基類: 子類A 子類B 子類C
橋接模式:
實現體系 定義包含具體實現方式
抽象體系調用實現體系以完成其操作。
抽象體系中的類會把實現體系中的某個類實例聚合進來,而這個實例將充當抽象接口與具體實現之間的橋樑。
這裏關鍵理解聚合進來是什麼意思。回想之前的適配器模式,就是把一個類聚合到適配器類中,幾個方法可以在一個方法中完成。
此次的實例是編寫一個類,來完成用特定算法繪製條形圖,具體的算法實現放在其他類中。
這裏其實和適配器模式有點類似,大家來看:
class BarCharter:
def __init__(self, renderer):
if not isinstance(renderer, BarRenderer):
raise TypeError('Exception object of {}'.format(type(render).__name__))
self.__renderer = renderer
def render(self, caption, pairs):
maximum = max(value for _, value in pairs)
self.__renderer.initialize(len(pairs), maximum)
self.__renderer.draw_caption(caption)
for name, value in pairs:
self.__renderer.draw_bar(name, value)
self.__renderer.finalize()
這個類就是用來抽象體系,在初始化裏面來判斷傳入的類型是否正確
def has_methods(*methods):
def decorator(Base):
def __subclasshook__(Class, Sublass):
if Class is Base:
attributes = collections.ChainMap(*(Superclass.__dict__ for Superclass in Sublass.__mro__))
if all(method in attributes for method in methods)
return True
return NotImplemented
Base.__subclasshook__ = classmethod(__subclasshook__)
return Base
return decorator
@has_methods("initialize", "draw_caption", "dram_bar", "finalize")
class BarRenderer(metaclass=abc.ABCMeta):
pass
而傳入的類型的接口此處用了類修飾器來生成,可對比上一篇 Python的結構型設計模式之適配器模式http://blog.csdn.net/zy_dream/article/details/69934300class TextBarRenderer:
def __init__(self, scaleFactor=40):
self.scaleFactor = scaleFactor
def initialize(self, bars, maximum):
assert bars > 0 and maximum > 0
self.scale = self.scaleFactor / maximum
def draw_caption(self, caption):
print ("{0:^{2}}\n{1:^{2}}".format(caption, "=" * len(caption), self.scaleFactor))
def draw_bar(self, name, value):
print ("{}{}".format("*" * int(value * self.scale), name))
def finalize(self):
pass
class ImageBarRender:
COLORS = [Image.color_for_name(name) for name in ("red", "green", "blue", "yellow", "magenta", "cyan")]
def __init__(self, stepHeight=10, barWidth=30, barGap=2):
self.stepHeight = stepHeight
self.barWidth = barWidth
self.barGap = barGap
def initialize(self, bars, maximum):
# 作圖
pass
def draw_caption(self, caption):
# 作圖
pass
def draw_bar(self, name, value):
# 作圖
pass
def finalize(self):
# 作圖
pass
最後就是兩個實現體系的生成,因 Image 模塊我暫時未安裝,直接帶過,但是這樣好像也挺簡單易懂的。
def main():
pairs = {("Mon", 11), ("Tue", 12), ("Wed", 13), ("Thu", 17), ("Fri", 24), ("Sat", 15), ("Sun", 13)}
textBarCharter = BarCharter(TextBarRenderer())
textBarCharter.render("Forecast 6/8", pairs)
imageBarCharter = BarCharter(ImageBarRender())
imageBarCharter.render("Forecast 6/8", pairs)
if __name__ == '__main__':
main()
通過橋接模式,是更加進一步理解了渲染接口的渲染器。render 接口裏面的方法,子類裏面必爲相同的行爲。
而如果這時候有其他一些相似功能的子類,其方法可能比接口裏面的多,或者少。此時類似於上面這兩個子類,就可以作爲其他子類的橋樑(也就是模仿吧)進行聚合,來成爲可以渲染的子類。即爲橋接模式。