专栏首页Python机器学习算法说书人Python设计模式(9):桥接模式

Python设计模式(9):桥接模式

导言

在实际生活中,某些事物由于自身的逻辑,具有两个或多个维度的变化。例如,国家武装力量分为海军、陆军、空军三个军种,海、陆、空三军各自又有军、师、旅、团、营等建制。对于各个军种,以上的建制单位所包含的人数是不一样的。陆军人数较多、空军人数较少。这样,就产生了两个维度,一个是军种维度,另一个是具体的各个军种的建制维度。在军种维度,可以增加例如“外空”的新军种;在建制维度,可以修改在各个军种中的人数,或者增加一个新的军事单位。

相应的,在软件设计中,如何应对这种“多维度的变化”?如何巧妙的设计软件,使得系统可以沿着两个或者多个维度进行独立的增加或者变化,而这种变化又不会对现有的类产生影响呢?这种情况可以使用桥接模式(Bridge Pattern),其意图是将一个软件的抽象部分与实现部分分离,使它们都可以独立的变化。

当一种抽象有几种不同实现方法的时候,一个有效的方法是使用面向对象的继承概念,将其设计为一个层次类,通常是使用抽象类代表抽象部分,而由其他具体的类继承该抽象类,以便用不同的方法实现抽象超类所声明的功能。但是这种方法并不永远是唯一正确的选择,有时这种设计会影响其扩展性,尤其是当该层次类包含两个维度的变化时更是如此。

桥接模式是指将抽象部分与它的实现部分分离。使它们可以独立地变化。桥接模式的设计类图如图所示。

桥接模式的各组成部分即含义说明如下。

  1. Abstraction 接口:定义抽象部分的接口,维持 Implementor 对象的一个参考(Reference)。
  2. RefindedAbstraction 类:是一个实类,继承或者实现 Abstraction。
  3. Implementor 接口:定义 Implementation 类的接口;Implementor 接口的结构形式可以不和 Abstraction 界面严格对应;Implementor 接口通常只提供比较原始的功能,Abstraction 接口通常提供比较高级的功能。
  4. ConcreateImplementor 类:是一个实类,实现 Implementor 接口。

当要避免抽象部分和实现部分的永久绑定,例如实现部分必须在运行时被选择的时候,使用桥接模式。

需要注意的是,抽象部分和实现部分都应该被子类继承。这样,桥接模式可以使用户结合不同的抽象对象与实现对象,并且独立地扩展抽象部分与实现部分。甚至 Abstraction 的具体实现类 RefinedAbstraction 改变了,客户程序都不必重新编译。

桥接模式有如下优点。

  1. 分离接口和实现部分。一个实现不必固定地绑定一个接口。抽象类的实现可以在系统运行时进行配置,一个对象甚至可以在运行时改变它的实现。
  2. 提高了可扩展性。可以独立地对 Absraction 和 Implementor 层次结构进行扩展。
  3. 实现细节对客户的透明。可以对客户隐藏实现细节。

桥接模式强调对象有两个以上维度的变化,简化多级继承关系,但同时增加了聚合对象的内部方法,因为它不得不多写方法以便包含它的类调用。

from abc import ABC, abstractmethod


class Abstraction(ABC):
    def __init__(self, implementor):
        self.implementor = implementor

    @abstractmethod
    def operation(self):
        pass


class RefinedAbstractionA(Abstraction):
    def operation(self):
        print('RefinedAbstractionA')
        self.implementor.operation_imp()


class RefinedAbstractionB(Abstraction):
    def operation(self):
        print('RefinedAbstractionB')
        self.implementor.operation_imp()


class Implementor(ABC):
    @abstractmethod
    def operation_imp(self):
        pass


class ConcreteImplementorA(Implementor):
    def operation_imp(self):
        print('ConcreteImplementorA')


class ConcreteImplementorB(Implementor):
    def operation_imp(self):
        print('ConcreteImplementorB')


class Client:
    @staticmethod
    def main():
        concrete = input('concrete:')
        abstract = input('abstract:')
        implementor = eval(f'ConcreteImplementor{concrete}()')
        implementor.operation_imp()
        abstraction = eval(f'RefinedAbstraction{abstract}(implementor)')
        abstraction.operation()


if __name__ == '__main__':
    Client.main()

本文分享自微信公众号 - Python机器学习算法说书人(Python-ML-Algorithm),作者:小陈学Python

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-03-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 魔法方法(2)

    在学习面向对象程序设计时,我们通常会学到存取方法,它们是名称类似于getHeight和setHeight的方法,用于获取和设置属性(这些属性可能是私有的)。如果...

    不可言诉的深渊
  • 用通俗易懂的语言讲解 kNN

    最近有个同学问我 k-means 和 kNN 是不是差不多?其实差太多了,k-means 是在不知道类别的情况下进行分类的,而 kNN 是通过已经存在的已经分好...

    不可言诉的深渊
  • 古老的机械钟表蕴含着神秘的数学原理

    时间是一个比较抽象的概念,是物质运动、变化的持续性、顺序性的表现。正因为人们需要研究物质的运动,就必须通过一个中介者来认识和度量时间,这个中介者就是计时器,从古...

    不可言诉的深渊
  • AlphaGo增强式学习算法:实现‘高手指点’特效

    我们在学习过程中离开不了老师的指导,老师除了传授知识外,另外一个很重要的作用是指出问题。我们或多或少有这样的经验,在训练某种技能时一开始进步很快,但不久就进入瓶...

    望月从良
  • python基础知识:类,对象,模块三者的区别

    面向对象技术是目前流行的系统设计开发技术,它包括面向对象分析和面向对象程序设计。面向对象程序设计技术的提出,主要是为了解决传统程序设计方法--结构化程序设计所不...

    HUBU生信
  • Python入门(9)

    大家好,在我们学习了python的模块以后,我们几乎可以编写完整的Python应用程序,甚至面对一些相对复杂的应用需求,我们还能通过包和模块来搭建一个漂亮的系统...

    高一峰
  • Python魔方方法详解

    https://fishc.com.cn/forum.php?mod=viewthread&tid=48793&extra=page%3D1%26filter%...

    py3study
  • 开发中使用throttle和debounce

    上面的两个问题解决后能大大提升用户体验 解决它们就用到了throttle和debounce

    剑行者
  • 可修改内容的优先级队列

    小锋学长
  • Python面试题目之列表去重并维持原来顺序

    Jetpropelledsnake21

扫码关注云+社区

领取腾讯云代金券