专业介绍:
将 "抽象" 与 "实现" 分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。
通俗介绍:
桥接模式的定义看似清晰,实则模糊,因为桥接模式是几十种设计模式中最复杂的模式之一!所以首先思维不能乱。
开始解释:
上面定义中的 "抽象" (abstraction)不再指的之前的抽象类中的抽象概念了,"实现"也不再是我们之前理解的那个实现了。这里的"抽象"而是指的抽象的事务,比如最终要的东西是宝马i8轿车,那么"轿车" 就是抽象(abstraction)的事物,"宝马i8" 是它的特征,就可以作为实现(implementation);再比如要的是白色的正方形,那么正方形就是抽象(abstraction)的事物,白色就是其特性,也就是实现(implementation)。
抽象(abstraction)指的是一个抽象的事物,实现(implementation)指的是具体行为或特征,是两个维度,都可以有多种变化,比如除了轿车还有火车卡车,除了宝马i8还有宝马X6甚至奔驰S600。
桥接模式中包含的角色:
抽象化角色(abstraction):一个抽象类,包含了多维度的属性,直接调用实现化角色,是处于最上层的角色。
扩展抽象化角色(RefinedAbstraction):一个具体类,实现了<抽象化角色>接口的<抽象化>部分。
实现化角色(Implementor):一个抽象类,定义实现化角色的接口,供扩展抽象化角色调用。
具体实现化角色(ConcreteImplementor):一个具体类,包含实现化角色的具体实现。
应用场景:
需要使用的对象(类)由两个或更多不同维度的属性组成,且这些不同维度的属性可以组合出不同的结果,那么此时桥接模式就能派上用场!
代码:
下面的代码解决上面的举例
# 桥接模式
import abc, six
# step-1: 定义<实现化>抽象类
@six.add_metaclass(abc.ABCMeta)
class Implementor:
@abc.abstractmethod
def get_brand(self): pass
# step-2: 定义具体<实现化>类
class ConcreteImplementor(Implementor):
def get_brand(self):
return 'BMW i8'
# step-3: 定义一个顶层的抽象角色,Car
@six.add_metaclass(abc.ABCMeta)
class AbstractCar:
_implementor: Implementor = None
def __init__(self, implementor: Implementor):
self._implementor = implementor
# 抽象角色直接调用<实现化>角色的方法
def get_brand(self):
return self._implementor.get_brand()
@abc.abstractmethod
def get_abstraction_item(self): pass
# step-4: 定义扩展<抽象>类: Refined Abstraction
class RefinedAbstractionHomeCar(AbstractCar):
def __init__(self, implementor: Implementor):
super(RefinedAbstractionHomeCar, self).__init__(implementor)
def get_brand(self):
# <实现化>信息直接调用父类的接口
return super().get_brand()
def get_abstraction_item(self):
"""主要返回<抽象化>事物"""
return 'home car' # 暂代指轿车
# step-4.1: 定义扩展<抽象>类: Refined Abstraction
class RefinedAbstractionTruck(AbstractCar):
def __init__(self, implementor: Implementor):
super().__init__(implementor)
def get_brand(self):
# <实现化>信息直接调用父类的接口
return super().get_brand()
def get_abstraction_item(self):
"""主要返回<抽象化>事物"""
return 'Truck' # 卡车
if __name__ == '__main__':
implementor = ConcreteImplementor()
refinedHomeCar = RefinedAbstractionHomeCar(implementor)
'''
扩展抽象类的意义在于:通过组合不同的<抽象化>属性,如轿车、卡车,和<实现化>属性,如BMW i8等
组合出具有不同属性(方法)的结果类,供使用
'''
print(refinedHomeCar.get_brand())
print(refinedHomeCar.get_abstraction_item())
refinedTruck = RefinedAbstractionTruck(implementor)
print(refinedTruck.get_brand())
print(refinedTruck.get_abstraction_item())
带来的问题:
对我来说,这个refined究竟该如何翻译也没弄清楚,许多资料使用的是扩展抽象角色,但感觉词不达意,会影响理解。
再一个就是这个模式的缺点,就是抽象化程度高了,要求设计者在设计的时候高度抽象化应用场景,分离的出<抽象化>和<实现化>部分,引入这个模式会导致系统复杂度直线上升,慎用!建议真实场景中简化使用此模式,只需要分离出不同维度的属性,然后定义不同的类,最后用组合的方式得到想要的类即可。
最后
在学习这个模式时,我翻阅了大部分国内的资料,基本一上来就给我讲怎么实现各种颜色的正方形,圆形。。。然后桥接模式就开场了,看了代码我也不知道到底为什么形状要用abstraction来写,形状要作为implementation,看的真是一脸懵逼,很多资料虽然不是同样的例子,但也没有说明为什么要这样做,到底桥接了什么。
所以,我选择Wikipedia,如果你初次了解桥接模式,想要了解第一手的官方性的资料,推荐维基百科-桥接模式。
备注:关于abc, six库的基本用法参考文章 简单工厂模式 & Python示例 底部的介绍,: )
欢迎留言~
参考文章:
https://zh.wikipedia.org/wiki/%E6%A9%8B%E6%8E%A5%E6%A8%A1%E5%BC%8F