用于将“抽象”(比如接口或算法)与实现方式相分离
若干基类
每个基类: 子类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 接口里面的方法,子类里面必为相同的行为。
而如果这时候有其他一些相似功能的子类,其方法可能比接口里面的多,或者少。此时类似于上面这两个子类,就可以作为其他子类的桥梁(也就是模仿吧)进行聚合,来成为可以渲染的子类。即为桥接模式。