源码地址:https://github.com/weilanhanf/PythonDesignPatterns

说明:

有些类在功能设计上要求,自身包含两个或两个以上变化的因素,即该类在二维或者多维上变化。现有一杯咖啡,咖啡杯的大小和是否加奶为两个变化因素,使得这杯咖啡在这两个维度上发生变化,也就是可以产生四个类:小杯不加奶,小杯加奶,大杯不加奶,大杯加奶。这样的话如果说在给咖啡多几个变化因素如:加糖,是否加热等,那么就会有呈指数增长个数的子类产生。但是我们可以从另一个角度考虑。这四个类其实是两个角色的组合,行为和抽象,抽象为大杯小杯,行为为加奶与否。这种分离抽象与行为的方法就是桥接模式。

桥接模式:将抽象部分与它的实现部分解耦,使得两者都能够独立变化适应业务需求,或者说是两个部分中的任何一部分发生变化时都不会影响对方,”井水不犯河水"。桥接模式桥接模式又被称为柄体(Handle and Body)模式或接口(Interface)模式 用抽象关联取代了传统的多层继承 将类之间的静态继承关系转换为动态的对象组合关系

桥接模式的结构

桥接模式包含以下4个角色: Abstraction(抽象类) RefinedAbstraction(扩充抽象类) Implementor(实现类接口) ConcreteImplementor(具体实现类)

实例:

在一个画图程序中,常会见到这样的情况:有一些预设的图形,如矩形、圆形等,还有一个对象-画笔,调节画笔的类型(如画笔还是画刷,还是毛笔效果等)并设定参数(如颜色、线宽等),选定图形,就可以在画布上画出想要的图形了。要实现以上需求,先从最抽象的元素开始设计,即形状和画笔

class Shape:
name=""
param=""
def __init__(self,*param):
pass
def getName(self):
return self.name
def getParam(self):
return self.name,self.param class Pen:
shape=""
type=""
def __init__(self,shape):
self.shape=shape
def draw(self):
pass #形状对象和画笔对象是最为抽象的形式。接下来,构造多个形状,如矩形和圆形
class Rectangle(Shape):
def __init__(self,long,width):
self.name="Rectangle"
self.param="Long:%s Width:%s"%(long,width)
print("Create a rectangle:%s"%self.param)
class Circle(Shape):
def __init__(self,radius):
self.name="Circle"
self.param="Radius:%s"%radius
print("Create a circle:%s"%self.param) #紧接着是构造多种画笔,如普通画笔和画刷:
class NormalPen(Pen):
def __init__(self,shape):
Pen.__init__(self,shape)
self.type="Normal Line"
def draw(self):
print("DRAWING %s:%s----PARAMS:%s"%(self.type,self.shape.getName(),self.shape.getParam()))
class BrushPen(Pen):
def __init__(self,shape):
Pen.__init__(self,shape)
self.type="Brush Line"
def draw(self):
print("DRAWING %s:%s----PARAMS:%s" % (self.type,self.shape.getName(), self.shape.getParam())) #业务中的逻辑如下:
if __name__=="__main__":
normal_pen=NormalPen(Rectangle("20cm","10cm"))
brush_pen=BrushPen(Circle("15cm"))
normal_pen.draw()
brush_pen.draw()

打印结果:

Create a rectangle:Long:20cm Width:10cm
Create a circle:Radius:15cm
DRAWING Normal Line:Rectangle----PARAMS:('Rectangle', 'Long:20cm Width:10cm')
DRAWING Brush Line:Circle----PARAMS:('Circle', 'Radius:15cm')

对象形状和画笔是最为抽象的形式。形状包括矩形和圆形,又可以在后期业务需求中扩展正方形,三角形等,画笔也可以由普通画笔和画刷扩展羽毛笔,水笔等多个类,很好的支持了开放封闭原则。最重要的是对象形状和画笔这两个部分可以独立变化却不受彼此的影响。

模式优点

分离抽象接口及其实现部分 可以取代多层继承方案,极大地减少了子类的个数 提高了系统的可扩展性,在两个变化维度中任意扩展一个维度,不需要修改原有系统,符合开闭原则

模式缺点

会增加系统的理解与设计难度,由于关联关系建立在抽象层,要求开发者一开始就针对抽象层进行设计与编程 正确识别出系统中两个独立变化的维度并不是一件容易的事情

模式适用环境

需要在抽象化和具体化之间增加更多的灵活性,避免在两个层次之间建立静态的继承关系 抽象部分和实现部分可以以继承的方式独立扩展而互不影响 一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立地进行扩展 不希望使用继承或因为多层继承导致系统类的个数急剧增加的系统

python-桥接模式的更多相关文章

  1. 设计模式-结构型模式,python桥接模式

    桥接模式 桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化.这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦. 这种模式涉及到一个作为桥接 ...

  2. 大话设计模式Python实现-桥接模式

    桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化. 下面是一个桥接模式的demo: #!/usr/bin/env python # -*- coding: ...

  3. 实例解析Python设计模式编程之桥接模式的运用

    实例解析Python设计模式编程之桥接模式的运用 这篇文章主要介绍了Python设计模式编程之桥接模式的运用,桥接模式主张把抽象部分与它的实现部分分离,需要的朋友可以参考下 我们先来看一个例子: #e ...

  4. [Python设计模式] 第22章 手机型号&软件版本——桥接模式

    github地址:https://github.com/cheesezh/python_design_patterns 紧耦合程序演化 题目1 编程模拟以下情景,有一个N品牌手机,在上边玩一个小游戏. ...

  5. python 设计模式之桥接模式 Bridge Pattern

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

  6. linux桥接模式下配置静态ip

    原文链接:http://blog.csdn.net/qq_37936542/article/details/79494993 一:桥接模式 VMware桥接模式,也就是将虚拟机的虚拟网络适配器与主机的 ...

  7. 桥接模式下访问虚拟机中的Django项目

    首先需要保证主机和虚拟机能相互Ping通,如果Ping不通,请参考我上篇文章,这里演示的是桥接模式下的方法,如果是NAT模式连接,请参考别处. 1. 虚拟机Linux系统内的Django项目 sett ...

  8. BridgePattern(桥接模式)

    /** * 桥接模式 * @author TMAC-J * 应用于多维度方案 * 用组合的形式代替继承 * 符合单一职责原则 * 一个类只有一个引起他变化的原因 * 增加程序灵活性 */ public ...

  9. PHP设计模式(八)桥接模式(Bridge For PHP)

    一.概述 桥接模式:将两个原本不相关的类结合在一起,然后利用两个类中的方法和属性,输出一份新的结果. 二.案例 1.模拟毛笔(转) 需求:现在需要准备三种粗细(大中小),并且有五种颜色的比 如果使用蜡 ...

  10. 设计模式(八)桥接模式(Bridge Pattern)

    一.引言 这里以电视遥控器的一个例子来引出桥接模式解决的问题,首先,我们每个牌子的电视机都有一个遥控器,此时我们能想到的一个设计是——把遥控器做为一个抽象类,抽象类中提供遥控器的所有实现,其他具体电视 ...

随机推荐

  1. Java并发编程总结3——AQS、ReentrantLock、ReentrantReadWriteLock

    本文内容主要总结自<Java并发编程的艺术>第5章——Java中的锁. 一.AQS AbstractQueuedSynchronizer(简称AQS),队列同步器,是用来构建锁或者其他同步 ...

  2. php获取指定日期的前一天,前一月,前一年日期

    ## php获取指定日期的前一天,前一月,前一年日期   前一天的日期为: date("Y-m-d",strtotime("-1 days",strtotime ...

  3. eslint 配置及规则说明

    中文官方网站 安装 可以全局安装,也可以在项目下面安装. 如下是在项目中安装示例,只需要在 package.json 中添加如下配置,并进行安装: “eslint”: “^4.11.0” 配置 配置方 ...

  4. 从官网下载指定版本的JDK

    从官网下载指定版本的JDK 一.百度搜索jdk,进入最新版Downloads界面 百度搜索jdk,或者jdk下载,点击进入jdk官网最新版本下载界面,可以看到当前最新版本为jdk12 二.找到JDK历 ...

  5. WebForm——JS检测浏览器是否是IE浏览器

    function IEVersion() { var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串 && userAgen ...

  6. odoo开发环境搭建(三):安装odoo依赖的python包

    odoo开发环境搭建(三):安装odoo依赖的python包 http://www.cnblogs.com/jlzhou/p/5940815.html

  7. android(java) 开发过程中经验及总结记录

    android(java) 开发过程中经验及总结记录

  8. android初探

    随着nodejs的不断发展,前端的范围越来越大,所以,适当的了解移动端是非常有必要的,比如使用RN开发app,前端必须要和安卓工程师沟通共同开发,那么学习android的基本知识就很重要了,因为目前安 ...

  9. python再探

    python是一门强大的高级编程语言,之前的文章中介绍了python的基础知识,接下来会介绍一些python更为高级的知识. 面向对象编程 基本知识 一般编程思想分为面向过程和面向对象,前者的基本单元 ...

  10. vue中请求本地的json数据

    为什么要请求本地的数据?模拟后台的请求数据,验证页面的逻辑是否存在问题,抛开后台提前开发等. 常用的说来有:jq的方式 约等于 axios的方式,vuex状态管理的方式 个人认为最好用的就是jq的方式 ...