美文网首页
设计模式(python实现)--桥接模式(Bridge)

设计模式(python实现)--桥接模式(Bridge)

作者: 远行_2a22 | 来源:发表于2020-01-28 16:33 被阅读0次

动机(Motivation)

  • 由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度,乃至多个纬度的变化。
  • 如何应对这种“多维度的变化”?如何利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化,而不引入额外的复杂度?

模式定义

将抽象部分(业务功能)与实现部分(平台实现)分离,使它们都可以独立地变化。
——《设计模式》GoF

要点总结

  • Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自纬度的变化,即“子类化”它们。
  • Bridge模式有时候类似于多继承方案,但是多继承方案往往违背单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方法。
  • Bridge模式的应用一般在“两个非常强的变化维度”,有时一个类也有多于两个的变化维度,这时可以使用Bridge的扩展模式。

例子

消息类一方面需要实现业务相关loginsend_message等接口。比如精简版的登录仅登录即可,完美版的登录还需要播放声音等额外功能。
另一方面也要实现平台相关相关的play_sounddraw_shape等接口。

一般实现

# -*- coding: utf-8 -*-
class Massage(object):
    # 业务相关接口, 不同业务版本,实现不同
    def login(self, user_name, password):
        pass

    def send_message(self, message):
        pass

    def send_picture(self, picture):
        pass

    # 平台相关接口,不同平台实现不同
    def play_sound(self):
        pass

    def draw_shape(self):
        pass

    def write_text(self):
        pass

    def connect(self):
        pass


# ----------------平台实现-------------------

class PCMassageBase(Massage):
    def play_sound(self):
        print('PCMassageBase, play_sound')

    def draw_shape(self):
        print('PCMassageBase, draw_shape')

    def write_text(self):
        print('PCMassageBase, write_text')

    def connect(self):
        print('PCMassageBase, connect')


class MobileMassageBase(Massage):
    def play_sound(self):
        print('MobileMassageBase, play_sound')

    def draw_shape(self):
        print('MobileMassageBase, draw_shape')

    def write_text(self):
        print('MobileMassageBase, write_text')

    def connect(self):
        print('MobileMassageBase, connect')


# ------------业务抽象------------
class PCMassageLite(PCMassageBase):
    # 精简版
    def login(self, user_name, password):
        print('PCMassageLite, login')
        self.connect()

    def send_message(self, message):
        print('PCMassageLite, send_message')
        self.write_text()

    def send_picture(self, picture):
        print('PCMassageLite, send_picture')
        self.draw_shape()


class PCMassagePerfect(PCMassageBase):
    # 完美版
    def login(self, user_name, password):
        print('PCMassagePerfect, login')
        self.connect()
        self.play_sound()

    def send_message(self, message):
        print('PCMassagePerfect, send_message')
        self.write_text()
        self.play_sound()

    def send_picture(self, picture):
        print('PCMassagePerfect, send_picture')
        self.draw_shape()
        self.play_sound()


class MobileMassageLite(MobileMassageBase):
    # 精简版
    def login(self, user_name, password):
        print('MobileMassageLite, login')
        self.connect()

    def send_message(self, message):
        print('MobileMassageLite, send_message')
        self.write_text()

    def send_picture(self, picture):
        print('MobileMassageLite, send_picture')
        self.draw_shape()


class MobileMassagePerfect(MobileMassageBase):
    # 完美版
    def login(self, user_name, password):
        print('MobileMassagePerfect, login')
        self.connect()
        self.play_sound()

    def send_message(self, message):
        print('MobileMassagePerfect, send_message')
        self.write_text()
        self.play_sound()

    def send_picture(self, picture):
        print('MobileMassagePerfect, send_picture')
        self.draw_shape()
        self.play_sound()


if __name__ == '__main__':
    pc_massage_lite = PCMassageLite()
    pc_massage_lite.login('root', 123)
    mobile_massage_perfect = MobileMassagePerfect()
    mobile_massage_perfect.login('root', 123)

仔细阅读 ,会发现:

  • 该版本有重复代码,PCMassageLiteMobileMassageLite, PCMassagePerfectMobileMassagePerfect除了父类不同外,其他都相同。
  • 需要定义的类的个数很多。平台有m种,业务版本有n种,那么需要1+n+m*n个类
  • 业务和平台是两个不同的变化维度,杂在Message中,耦合过高

桥接模式实现

# -*- coding: utf-8 -*-


class Massage(object):
    # 业务相关接口, 不同业务版本,实现不同
    def __init__(self, massage_imp):
        self.massage_imp = massage_imp

    def login(self, user_name, password):
        pass

    def send_message(self, message):
        pass

    def send_picture(self, picture):
        pass


class MassageImp(object):
    # 平台相关接口,不同平台实现不同
    def play_sound(self):
        pass

    def draw_shape(self):
        pass

    def write_text(self):
        pass

    def connect(self):
        pass


# ----------------平台实现-------------------

class PCMassageImp(MassageImp):
    def play_sound(self):
        print('PCMassageImp, play_sound')

    def draw_shape(self):
        print('PCMassageImp, draw_shape')

    def write_text(self):
        print('PCMassageImp, write_text')

    def connect(self):
        print('PCMassageImp, connect')


class MobileMassageImp(MassageImp):
    def play_sound(self):
        print('MobileMassageImp, play_sound')

    def draw_shape(self):
        print('MobileMassageImp, draw_shape')

    def write_text(self):
        print('MobileMassageImp, write_text')

    def connect(self):
        print('MobileMassageImp, connect')


# ------------业务抽象------------
class MassageLite(Massage):

    def login(self, user_name, password):
        print('MassageLite, login')
        self.massage_imp.connect()

    def send_message(self, message):
        print('MassageLite, send_message')
        self.massage_imp.write_text()

    def send_picture(self, picture):
        print('MassageLite, send_picture')
        self.massage_imp.draw_shape()


class MassagePerfect(Massage):
    # 完美版
    def login(self, user_name, password):
        print('MassagePerfect, login')
        self.massage_imp.connect()
        self.massage_imp.play_sound()

    def send_message(self, message):
        print('MassagePerfect, send_message')
        self.massage_imp.write_text()
        self.massage_imp.play_sound()

    def send_picture(self, picture):
        print('MassagePerfect, send_picture')
        self.massage_imp.draw_shape()
        self.massage_imp.play_sound()


if __name__ == '__main__':
    pc_massage_imp = PCMassageImp()
    pc_massage_lite = MassageLite(pc_massage_imp)
    pc_massage_lite.login('root', 123)

    print('-'*30)
    mobile_massage_imp = MobileMassageImp()
    mobile_massage_perfect = MassagePerfect(mobile_massage_imp)
    mobile_massage_perfect.login('root', 123)

变化点主要有以下几点:

  • 桥接模式将业务和平台两个维度的变化拆分为了两个类, 使它们可以独立地变化。
  • 将原来的继承,改为了组合。原先PCMassageLite通过继承PCMassageBaselogin接口中访问对应的self.connect()
    桥接模式MassageLite,通过组合login接口中访问对应的self.massage_imp.connect()
  • 需要定义的类的个数大幅度减少。平台有m种,业务版本有n种,那么需要2+n+m个类

相关文章

  • 桥接模式

    设计模式:桥接模式(Bridge)

  • 设计模式-桥接模式

    设计模式-桥接模式 定义 桥接模式(Bridge Pattern)也称为桥梁模式、接口(Interface)模式或...

  • 设计模式(python实现)--桥接模式(Bridge)

    动机(Motivation) 由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度,乃至多个纬度的变化。 如何...

  • 设计模式之桥接模式

    设计模式之桥接模式 Intro 桥接模式(Bridge),将抽象部分与它的实现部分分离,使得它们都可以独立地变化。...

  • Java设计模式之桥接模式

    概念 桥接模式:亦称Bridge模式,构造型设计模式之一。  将抽象部分(abstraction)和它的实现部分(...

  • 桥接模式

    桥接(Bridge)模式的定义如下:将抽象与实现分离,使它们可以独立变化。 桥接(Bridge)模式的优点是:由于...

  • 桥接模式

    介绍 桥接模式(Bridge Pattern) 也称为桥梁模式,是结构型设计模式之一。桥接模式的作用就是连接 "两...

  • 桥接模式-原理类图

    桥接模式(Bridge)-基本介绍 桥接模式(Bridge模式)是指:将实现与抽象放在两个不同的类层次中,使两个层...

  • iOS桥接模式

    桥接模式 桥接(Bridge Pattern)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式...

  • 设计模式之桥接器模式详解(附源代码)

    桥接模式 桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,...

网友评论

      本文标题:设计模式(python实现)--桥接模式(Bridge)

      本文链接:https://www.haomeiwen.com/subject/sampthtx.html