【通俗说设计模式】九、桥接模式 & Python示例

专业介绍:

将 "抽象" 与 "实现" 分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。

通俗介绍:  

桥接模式的定义看似清晰,实则模糊,因为桥接模式是几十种设计模式中最复杂的模式之一!所以首先思维不能乱。

开始解释:

       上面定义中的 "抽象" (abstraction)不再指的之前的抽象类中的抽象概念了,"实现"也不再是我们之前理解的那个实现了。这里的"抽象"而是指的抽象的事务,比如最终要的东西是宝马i8轿车,那么"轿车" 就是抽象(abstraction)的事物,"宝马i8" 是它的特征,就可以作为实现(implementation);再比如要的是白色的正方形,那么正方形就是抽象(abstraction)的事物,白色就是其特性,也就是实现(implementation)。

抽象(abstraction)指的是一个抽象的事物,实现(implementation)指的是具体行为或特征,是两个维度,都可以有多种变化,比如除了轿车还有火车卡车,除了宝马i8还有宝马X6甚至奔驰S600。

桥接模式中包含的角色
抽象化角色(abstraction):一个抽象类,包含了多维度的属性,直接调用实现化角色,是处于最上层的角色。

扩展抽象化角色(RefinedAbstraction):一个具体类,实现了<抽象化角色>接口的<抽象化>部分。

实现化角色(Implementor):一个抽象类,定义实现化角色的接口,供扩展抽象化角色调用。

具体实现化角色(ConcreteImplementor):一个具体类,包含实现化角色的具体实现。

应用场景:

扫描二维码关注公众号,回复: 15723774 查看本文章

     需要使用的对象(类)由两个或更多不同维度的属性组成,且这些不同维度的属性可以组合出不同的结果,那么此时桥接模式就能派上用场!


代码:

下面的代码解决上面的举例

# 桥接模式
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

猜你喜欢

转载自blog.csdn.net/sc_lilei/article/details/103406018