zoukankan      html  css  js  c++  java
  • python-桥接模式

    源码地址: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')

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

    模式优点

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

    模式缺点

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

    模式适用环境

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

  • 相关阅读:
    atitit.组件化事件化的编程模型--服务端控件(1)---------服务端控件与标签的关系
    atitit. 浏览器插件 控件 applet 的部署,签名总结 浏览器 插件 控件 的签名安全机制o9o
    Atitit. 解压缩zip文件 的实现最佳实践 java c# .net php
    atitit. applet 浏览器插件 控件 的环境,开发,提示总结o9o
    Atitit..文件上传组件选型and最佳实践总结(3)----断点续传控件的实现
    Atitit..文件上传组件选型and最佳实践总结(2)----断点续传
    Atitit.guice3 ioc 最佳实践 o9o
    Atitit. C# java 的api 目录封装结构映射总结
    atitit. 统计功能框架的最佳实践(1)---- on hibernate criteria
    Atitit.Hibernate中Criteria 使用总结and 关联查询 and 按照子对象查询 o9o
  • 原文地址:https://www.cnblogs.com/welan/p/9127087.html
Copyright © 2011-2022 走看看