设计模式之结构型模式: 桥接模式

一、简介

桥接模式是一种很实用的结构型设计模式,在软件开发时,如果某个类存在两个独立变化的维度,可以运用桥接模式将这两个维度分离出来,使两者可以独立扩展,让系统更加符合“单一职责原则”。

与多层继承方案不同,它将两个独立变化的维度设计为两个独立的继承等级结构,并且在抽象层建立一个抽象关联,该关联关系就像一条桥一样,将两个独立继承结构的类联接起来,故名桥接模式。

可以明显看出,桥接模式使用组合代替了继承,将类之间的静态继承关系转换为动态的对象组合关系,使用组合而不用继承,会使系统更加灵活,并易于扩展,同时有效控制了系统中类的个数

桥接定义如下:

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


主要解决:在有多种可能会变化的情况下,用继承会造成类爆炸问题,扩展起来不灵活。

何时使用:实现系统可能有多个角度分类,每一种角度都可能变化。

如何解决:把这种多角度分类分离出来,让它们独立变化,减少它们之间耦合。

 

二、具体实例:以汽车在公路上行驶为例

第一步:创建一个抽象类--公路基类

class AbstractRoad(object):
    '''公路基类'''
    pass

第二步:创建两个具体类--高速公路和市区道路

class SpeedWay(AbstractRoad):
    '''高速公路'''
    def __str__(self):
        return "高速公路"
class Street(AbstractRoad):
    '''市区街道'''
    def __str__(self):
        return "市区街道"

第三步:创建一个抽象类--车类 建立与道路的联系(相当于车辆跟道路有了关联)

class AbstractCar(object):
    '''车辆基类'''
    road = None

    def run(self):
        raise NotImplementedError

第四步:创建两个具体类--小汽车类和公交车类

class Car(AbstractCar):
    '''小汽车'''
    road = None
    def run(self):
        print("小汽车在%s行驶"% self.road)
class Bus(AbstractCar):
    '''公共汽车'''
    road = None
    def run(self):
        print("公共汽车在%s行驶"% self.road)

第五步:完成完整的逻辑功能

if __name__ == "__main__":
    # 小汽车在高速上行驶
    road1 = SpeedWay()
    car = Car()
    car.road = road1
    car.run()

    # 公共汽车在市区街道行驶
    road2 = Street()
    bus = Bus()
    bus.road = road2
    bus.run()

输出结果:

# 小汽车在高速公路行驶
# 公共汽车在市区街道行驶

 

应用设计模式:
       桥接模式(Bridge)来做(多维度变化);
       结合上面的例子,增加一个维度"人",不同的人开着不同的汽车在不同的路上行驶(三个维度);
       结合上面增加一个类"人",并重新调用.
代码实现:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

class AbstractRoad(object):
    '''公路基类'''
    pass


class AbstractCar(object):
    '''车辆基类'''
    road = None

    def run(self):
        raise NotImplementedError


class Street(AbstractRoad):
    '''市区街道'''
    def __str__(self):
        return "市区街道"


class SpeedWay(AbstractRoad):
    '''高速公路'''
    def __str__(self):
        return "高速公路"


class Car(AbstractCar):
    '''小汽车'''
    road = None
    def run(self):
        print("小汽车在%s行驶"% self.road)


class Bus(AbstractCar):
    '''公共汽车'''
    road = None
    def run(self):
        print("公共汽车在%s行驶"% self.road)


class AbstractPeople(object):
    car = None

    def drive(self):
        raise NotImplementedError


class Man(AbstractPeople):
    car = None
    def drive(self):
        print('男人驾驶',end='')
        self.car.run()

if __name__ == "__main__":
    # 小汽车在高速上行驶
    road1 = SpeedWay()
    car = Car()
    car.road = road1
    car.run()

    # 公共汽车在市区街道行驶
    road2 = Street()
    bus = Bus()
    bus.road = road2
    bus.run()

    # 男人驾驶小汽车在市区街道行驶
    man = Man()
    road3 = Street()
    car = Car()
    car.road = road3
    man.car = car
    man.drive()
View Code

 

三、直接继承模式和桥接模式的对比

 

 直接继承模式:对应到相应的类中,将是1+2+4=7个有继承关系的类,如果这时再加一个乡村道路,无疑是要多增加3个类,会带来类的急剧增长。

 

 

 

桥接模式:如果将道路和交通工具分开,对应到类设计中,只需要6个类,如果增加多一条路:乡村道路,只需增加一个类,增加一款新的交通工具:货车,也只需增加一个类。

这种处理多维变化(汽车和道路)的方式运用到软件设计中就是桥接模式。

 

四、桥接模式的优缺点和使用场景

优点: 1、抽象和实现的分离。 2、优秀的扩展能力。 3、实现细节对客户透明。

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

使用场景: 1、如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。 2、对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。 3、一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。

注意事项:对于两个独立变化的维度,使用桥接模式再适合不过了。

 


参考链接:https://www.jianshu.com/p/6a86ae4fb5bf
posted @ 2021-06-04 13:42  麟灬  阅读(165)  评论(0)    收藏  举报