10.设计模式之八:桥接模式【结构型模式】

在现实生活中,某些类具备两个或多个维度的变化,如图形既可按形状分,又可按颜色分。如何设计相似于 Photoshop 这样的软件,能画不一样形状和不一样颜色的图形呢?若是用继承方式,m 种形状和 n 种颜色的图形就有 m×n 种,不但对应的子类不少,并且扩展困难。python

固然,这样的例子还有不少,如不一样颜色和字体的文字、不一样品牌和功率的汽车、不一样性别和职业的男女、支持不一样平台和不一样文件格式的媒体播放器等。若是用桥接模式就能很好地解决这些问题。编程

定义与特色

桥接(Bridge)模式的定义以下:将抽象与实现分离,使它们能够独立变化。它是用组合关系代替继承关系来实现,从而下降了抽象和实现这两个可变维度的耦合度。字体

桥接(Bridge)模式的优势是:spa

  • 因为抽象与实现分离,因此扩展能力强;
  • 其实现细节对客户透明。

缺点是:因为聚合关系创建在抽象层,要求开发者针对抽象化进行设计与编程,这增长了系统的理解与设计难度。设计

结构与实现

能够将抽象化部分与实现化部分分开,取消两者的继承关系,改用组合关系。code

1. 模式的结构

桥接(Bridge)模式包含如下主要角色。对象

  1. 抽象化(Abstraction)角色:定义抽象类,并包含一个对实现化对象的引用。
  2. 扩展抽象化(Refined    Abstraction)角色:是抽象化角色的子类,实现父类中的业务方法,并经过组合关系调用实现化角色中的业务方法。
  3. 实现化(Implementor)角色:定义实现化角色的接口,供扩展抽象化角色调用。
  4. 具体实现化(Concrete Implementor)角色:给出实现化角色接口的具体实现。

2. 模式的实现

class Implemter(object):
    def OperatiomImpl(self):
        pass

class ConcreteImplementA(Implemter):
    def OperatiomImpl(self):
        print('ConcreteImplement A')

class ConcreteImplementB(Implemter):
    def OperatiomImpl(self):
        print('ConcreteImplement B')

class Abstraction(object):
    _imple = None
    def __init__(self, imple):
        self._imple = imple

    def operation(self):
        pass

class RefinedAbstrcation(Abstraction):
    def __init__(self, imple):
        super().__init__(imple)

    def operation(self):
        print('扩展抽象化(Refined Abstraction)角色被访问')
        self._imple.OperatiomImpl()

if __name__ == '__main__':
    imple = ConcreteImplementA()
    abs = RefinedAbstrcation(imple)
    abs.operation()

应用实例

用桥接(Bridge)模式模拟女士皮包的选购。blog

分析:女士皮包有不少种,能够按用途分、按皮质分、按品牌分、按颜色分、按大小分等,存在多个维度的变化,因此采用桥接模式来实现女士皮包的选购比较合适。继承

本实例按用途分可选钱包(Wallet)和挎包(HandBag),按颜色分可选黄色(Yellow)和红色(Red)。能够按两个维度定义为颜色类和包类。接口

  • 颜色类(Color)是一个维度,定义为实现化角色,它有两个具体实现化角色:黄色和红色,经过 getColor() 方法能够选择颜色;
  • 包类(Bag)是另外一个维度,定义为抽象化角色,它有两个扩展抽象化角色:挎包和钱包,它包含了颜色类对象,经过 getName() 方法能够选择相关颜色的挎包和钱包。

class Color(object):
    def get_color(self):
        pass

class Yellow(Color):
    def get_color(self):
        return "黄色"

class Red(Color):
    def get_color(self):
        return '红色'

class Bag(object):
    _color = None
    def set_color(self, color):
        self._color = color

    def get_name(self):
        pass

class HandBag(Bag):
    def get_name(self):
        print(self._color.get_color(), "挎包")

class Wallet(Bag):
    def get_name(self):
        print(self._color.get_color(), "钱包")

if __name__ == '__main__':
    y = Yellow()
    r = Red()

    hb = HandBag()
    hb.set_color(y)
    hb.get_name()

桥接模式的应用场景

桥接模式一般适用于如下场景。

  1. 当一个类存在两个独立变化的维度,且这两个维度都须要进行扩展时。
  2. 当一个系统不但愿使用继承或由于多层次继承致使系统类的个数急剧增长时。
  3. 当一个系统须要在构件的抽象化角色和具体化角色之间增长更多的灵活性时。

桥接模式模式的扩展

在软件开发中,有时桥接(Bridge)模式可与适配器模式联合使用。当桥接(Bridge)模式的实现化角色的接口与现有类的接口不一致时,能够在两者中间定义一个适配器将两者链接起来,其具体结构图如图所示。

相关文章
相关标签/搜索