#写在前面

前面写了那么设计模式了,有没有觉得有些模式之间很类似,甚至感觉作用重叠了,模式并不是完全隔离和独立的,有的模式内部其实用到了其他模式的技术,但是又有自己的创新点,如果一味地认为每个模式都是独一无二,与其他模式完全区别的,这是一种误区

#引入模式动机

这个例子清晰而直白的说明了为啥要用桥接模式,我就拿过来用了,链接在参考里

    设想如果要绘制矩形、圆形、椭圆、正方形,我们至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,如红色、绿色、蓝色等,此时至少有如下两种设计方案:
        • 第一种设计方案是为每一种形状都提供一套各种颜色的版本。

• 第二种设计方案是根据实际需要对形状和颜色进行组合。

 

对于有两个变化维度(即两个变化的原因)的系统,采用方案二来进行设计系统中类的个数更少,且系统扩展更为方便。设计方案二即是桥接模式的应用。桥接模式将继承关系转换为关联关系,从而降低了类与类之间的耦合,减少了代码编写量。

#模式定义

桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。

通俗点讲就是在不同的地方之间搭一座桥,让他们连接起来,可以相互通讯和使用。
在模式中,就是为被分离了的抽象部分和实现部分来搭桥。
桥接模式中的桥接是单向的,也就是只能是抽象部分的对象去使用实现部分的对象,而不能反过来,也就是个单向桥。

抽象化角色就像是一个水杯的手柄,而实现化角色和具体实现化角色就像是水杯的杯身。手柄控制杯身,这就是此模式别名“柄体”的来源。

#涉及角色

抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用。
修正抽象化(Refined Abstraction)角色:扩展抽象化角色,改变和修正父类对抽象化的定义。
实现化(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以非常不一样。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。

具体实现化(Concrete Implementor)角色:这个角色给出实现化角色接口的具体实现

这些是从百度百科抄的

#桥接模式分析

桥梁模式的用意是"将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化"。这句话有三个关键词,也就是抽象化、实现化和脱耦。

1)抽象化

存在于多个实体中的共同的概念性联系,就是抽象化。作为一个过程,抽象化就是忽略一些信息,从而把不同的实体当做同样的实体对待

2)实现化

抽象化给出的具体实现,就是实现化

3)脱耦

所谓耦合,就是两个实体的行为的某种强关联。而将它们的强关联去掉,就是耦合的解脱,或称脱耦。在这里,脱耦是指将抽象化和实现化之间的耦合解脱开,或者说是将它们之间的强关联改换成弱关联。

将两个角色之间的继承关系改为聚合关系,就是将它们之间的强关联改换成为弱关联。因此,桥梁模式中的所谓脱耦,就是指在一个软件系统的抽象化和实现化之间使用组合/聚合关系而不是继承关系,从而使两者可以相对独立地变化。这就是桥梁模式的用意。

这些是从百度百科抄的

#桥接模式的优点

    • 分离抽象接口及其实现部分。
    • 桥接模式有时类似于多继承方案,但是多继承方案违背了类的单一职责原则(即一个类只有一个变化的原因),复用性比较差,而且多继承结构中类的个数非常庞大,桥接模式是比多继承方案更好的解决方法。
    • 桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统。
    • 实现细节对客户透明,可以对用户隐藏实现细节。

#桥接模式的缺点

• 桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。

• 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性。

#桥接模式的应用场景

1)Java语言通过Java虚拟机实现了平台的无关性

2)JDBC驱动器

桥梁模式在Java应用中一个非常典型的例子就是JDBC驱动器。JDBC为所有的关系型数据库提供一个通用的界面。一个应用系统动态的选择一个合适的驱动器,然后通过驱动器向数据库引擎发出指令。这个过程就是将抽象角色的行为委派给实现角色的过程。

抽象角色可以针对任何数据库引擎发出查询指令,因为抽象角色并不直接�与数据库引擎打交道,JDBC驱动器负责这个底层的工作。由于JDBC驱动器的存在,应用系统可以不依赖于数据库引擎的细节而独立的演化;同时数据库引擎也可以独立�于应用系统的细节而独立的演化。两个独立的等级结构图如下图所示,左边是JDBC API的等级结构,右边是JDBC驱动器的等级结构,应用程序是建立在JDBC API的基础之上的。

JDBC等级结构图

应用系统作为一个等级结构,与JDBC驱动器这个等级结构是相对独立的,它们之间没有静态的强关联。应用系统通过委派与JDBC驱动器相互作用,这是一个桥梁模式的例子。

JDBC这种架构,把抽象部分和具体实现部分分离开来,从而使得抽象部分和具体实现部分都可以独立的扩展。对于应用程序而言,之遥选用不同的驱动,就可以让程序操作不同的数据库,而无需更改应用程序,从而实现在不同的数据库上移植;对于驱动程序而言,为数据库实现不同的驱动程序,并不会影响应用程序。

#适合使用桥接模式的情景

    • 如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
    • 抽象化角色和实现化角色可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。
    • 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
    • 虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。
    • 对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
 
 

#类结构

# 接口实现类
class Implementor:
def Operation(self):
raise NotImplementedError class ConcreteImplementorA(Implementor):
def Operation(self):
print("实现 A的方法") class ConcreteImplementorB(Implementor):
def Operation(self):
print("实现 B的方法")
# 抽象类
class Abstraction():
def __init__(self,implementor):
self.implementor = implementor
def Operation(self):
raise NotImplementedError class RefineAbstraction(Abstraction):
def Operation(self):
self.implementor.Operation() if __name__ == "__main__":
a = ConcreteImplementorA()
b = ConcreteImplementorB()
aa = RefineAbstraction(a)
ab = RefineAbstraction(b)
aa.Operation()
ab.Operation()
 
#举个例子

#抽象类:人
class people:
def set_skill(self,skill):
self.skill=skill
def perform_skill(self):
pass #具体抽象类:花匠
class hua_j(people):
def perform_skill(self):
print('我是花匠')
self.skill.perform_skill()
#具体抽象类:木匠
class mu_j(people):
def perform_skill(self):
print('我是木匠')
self.skill.perform_skill()
#具体抽象类:铁匠
class tie_j(people):
def perform_skill(self):
print('我是铁匠')
self.skill.perform_skill() #功能类,也是实现类
class skill:
def perform_skill(self):
pass #具体功能类,也是具体实现类 种花
class skill_hua(skill):
def perform_skill(self):
print('我会种花') #具体功能类,也是具体实现类 做木桌子
class skill_mu:
def perform_skill(self):
print('我会做木桌子') #具体功能类,也是具体实现类 做铁桌子
class skill_tie:
def perform_skill(self):
print('我会做铁桌子') #具体功能类,也是具体实现类 做老师
class skill_teacher:
def perform_skill(self):
print('我会做老师,可以教学生')
#具体功能类,也是具体实现类 做家具
class skill_jj:
def perform_skill(self):
print('我会做家具') def main():
h=hua_j() #花匠
m=mu_j() #木匠
t=tie_j() #铁匠 sh=skill_hua()# 本事:会种花
sm=skill_mu() #本事:会做木头桌子
st=skill_tie() #本事:会做铁桌子
s_t=skill_teacher() #本事:会教学生
s_jj=skill_jj() #本事:会做家具 h.set_skill(sh) #给花匠set种花的本事
h.perform_skill() #花匠 种花
h.set_skill(s_t) #给花匠set做老师的本事
h.perform_skill() #花匠教学生 print('=============')
m.set_skill(sm) #给木匠set 做木桌子的本事
m.perform_skill() #木匠 做木桌子
m.set_skill(s_t) #给木匠set做老师的本事
m.perform_skill() #木匠教学生
m.set_skill(s_jj) #给木匠set做家具的本事
m.perform_skill() #木匠做家具 print('=============')
t.set_skill(st) #给木匠set 做木桌子的本事
t.perform_skill() #木匠 做木桌子
t.set_skill(s_t) #给木匠set做老师的本事
t.perform_skill() #木匠教学生
t.set_skill(s_jj) #给木匠set做家具的本事
t.perform_skill() #木匠做家具 if __name__ == '__main__':
main()
 
 

参考

https://www.cnblogs.com/WindSun/p/10260547.html

https://baike.baidu.com/item/%E6%A1%A5%E6%8E%A5%E6%A8%A1%E5%BC%8F/5293399?fr=aladdin

https://www.cnblogs.com/zyrblog/p/9233189.html

https://blog.csdn.net/sunyqcn/article/details/85113751

https://www.jianshu.com/p/775cb53a4da2

https://www.cnblogs.com/qq_841161825/articles/10142201.html

https://blog.csdn.net/weixin_41431904/article/details/80783839

python 设计模式之桥接模式 Bridge Pattern的更多相关文章

  1. 乐在其中设计模式(C#) - 桥接模式(Bridge Pattern)

    原文:乐在其中设计模式(C#) - 桥接模式(Bridge Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 桥接模式(Bridge Pattern) 作者:webabcd 介绍 ...

  2. 【设计模式】桥接模式 Bridge Pattern

    开篇还是引用吕振宇老师的那篇经典的文章<设计模式随笔-蜡笔与毛笔的故事>.这个真是太经典了,没有比这个例子能更好的阐明桥接模式了,这里我就直接盗来用了. 现在市面上卖的蜡笔很多,各种型号, ...

  3. 二十四种设计模式:桥接模式(Bridge Pattern)

    桥接模式(Bridge Pattern) 介绍将抽象部分与它的实现部分分离,使它们都可以独立地变化. 示例有一个Message实体类,对它的操作有Insert()和Get()方法,现在使这些操作的抽象 ...

  4. 桥接模式(Bridge Pattern)

    1,定义           桥接模式(Bridge Pattern),也称为桥梁模式,其用意是将抽象化与实现化脱耦,使得两者可以独立的变化,它可以使软件系统沿着多个方向进行变化,而又不引入额外的复杂 ...

  5. Net设计模式实例之桥接模式( Bridge Pattern)

    一.桥接模式简介(Brief Introduction) 桥接模式(Bridge Pattern),将抽象部分与它的实现部分分离,使的抽象和实现都可以独立地变化. Decouple an abstra ...

  6. 转:设计模式-----桥接模式(Bridge Pattern)

    转自:http://www.cnblogs.com/houleixx/archive/2008/02/23/1078877.html 记得看原始链接的评论. 学习设计模式也有一段时间了,今天就把我整理 ...

  7. C#设计模式——桥接模式(Bridge Pattern)

    一.概述在软件开发中,我们有时候会遇上一个对象具有多个变化维度.比如对汽车对象来说,可能存在不同的汽车类型,如公共汽车.轿车等,也可能存在不同的发动机,如汽油发动机.柴油发动机等.对这类对象,可应用桥 ...

  8. [设计模式] 7 桥接模式 bridge

    #include<iostream> using namespace std; class AbstractionImp { public: virtual ~AbstractionImp ...

  9. python 设计模式之工厂模式 Factory Pattern (简单工厂模式,工厂方法模式,抽象工厂模式)

    十一回了趟老家,十一前工作一大堆忙成了狗,十一回来后又积累了一大堆又 忙成了狗,今天刚好抽了一点空开始写工厂方法模式 我看了<Head First 设计模式>P109--P133 这25页 ...

随机推荐

  1. mysql学习之基础篇03

    我们今天来进行建表的基本操作: 首先要建表就要了解列类型,因为建表就是声明列的过程,列声明完成了,表也就建好了. mysql中列分为三大类: 一.数值型 数值型又分为整型和浮点型两种. 先来看整型: ...

  2. SQL 执行 底层原理(一)

    一.SQL Server组成部分 1.关系引擎:主要作用是优化和执行查询.包含三大组件: (1)命令解析器:检查语法和转换查询树. (2)查询执行器:优化查询. (3)查询优化器:负责执行查询. 2. ...

  3. 在linux上搭建SVN服务器并自动更新至WEB目录

    1.仓库放在 /var/svn/ 目录下,并且仓库名为 project 2.创建用户组user,该组下添加两个成员user1.user2,密码直接用用户名,两用户可以checkout代码和提交代码 3 ...

  4. C# 如何取消BackgroundWorker异步操作

    BackgroundWorker 在执行DoWork事件时该如何取消呢? 方法1 DoWork 执行一个(耗时)循环 方法2 DoWork执行一个(耗时)方法[注:方法没有循环] 见代码: 方法1中D ...

  5. AHOI2013 差异 和 BZOJ3879 SvT

    差异 题目描述 给定一个长度为 $n$ 的字符串 $S$,令 $T_i$ 表示它从第 $i$ 个字符开始的后缀.求 $\displaystyle \sum_{1\leqslant i<j\leq ...

  6. Analysis of algorithms: observation

    例子: 3-Sum 给定N个整数,这里面有多少个三元组,使其三个整数相加为0,如上面的例子为有4个三元组. 这个问题是许多问题如计算机几何,图形学等的基础. 用简单粗暴的方式来解决3-Sum问题 通过 ...

  7. 《转》BAT批处理教程

    第一章 批处理基础第一节 常用批处理内部命令简介 批处理定义:顾名思义,批处理文件是将一系列命令按一定的顺序集合为一个可执行的文本文件,其扩展名为BAT或者CMD.这些命令统称批处理命令.小知识:可以 ...

  8. 180908 python 字符串内建函数

    Python 的字符串内建函数 Python 的字符串常用内建函数如下: 序号 方法及描述 1 capitalize()将字符串的第一个字符转换为大写 2 center(width, fillchar ...

  9. override关键字

    https://www.cnblogs.com/xinxue/p/5471708.html 2  重写 (override) 在 1.2.2 中提到 override 关键字,可以避免派生类中忘记重写 ...

  10. 原生javascript禁用和屏蔽鼠标右键

    (function(){ var doc=document, ua = navigator.userAgent.toLowerCase(), check = function(r){return r. ...