注意:如果不想浪费时间,请一定要点我。
在现实生活中,有些类具有多个维度的变化,比如图形既可以按照形状划分,又可以按照颜色划分;手机既可以按照品牌划分,又可以按照功能划分;人类既可以按照职业划分,又可以按照性别划分等等。
定义
将抽象部分和它的实现部分分离,使它们可以独立的变化。
实现系统可能有多角度分类,每一种分类都有可能变化,那么就将这种多角度分离出来让它们独立变化,减少它们之间耦合,通过使用组合关系替代继承关系方式。
桥接模式的优点如下:
(1)抽象和实现分离,降低耦合度。
(2)实现细节对用户透明。模式的实现
如果现在有两种品牌的手机 M、N,每种手机包括两个软件:通讯录和游戏,你应该如何设计它们之间的关系。
第一种设计方方案:
这种方式无论是新增一个品牌还是一款软件,将不得不修改它们的子类,并且会增加大量的类,所以我们想出第二种设计方案,当然下边这种还是存在同样的问题。
出现这种问题的原因就是使用了继承,如果按照功能划分,则将功能进行抽象,然后每个品牌去继承该抽象功能类;如果按照品牌划分,则将品牌进行抽象,然后每种功能去继承该抽象品牌类。这种继承结构,如果不断增加新品牌或者新功能,都会影响到之前的类。
对象的继承关系在编译时就定义好了,所以无法再运行时改变从父类继承的实现,子类的实现和父类的有非常紧密的依赖关系,导致父类的变化必然会导致子类发生变化。当你需要复用子类时,如果继承下来的实现不适合解决新问题,则父类必须重写或者被其他更适合的类进行替换,这种依赖关系限制了灵活性并最终限制了复用性。
所以,我们的其中一个设计原则就是合成复用原则,优先使用组合/聚合,而不是继承。
桥接模式可以将抽象和实现分开,取消二者的继承关系,改用组合关系。
桥接模式的角色如下:
(1)抽象角色:定义一个抽象类,并包含一个对实现对象的引用。
(2)扩展抽象角色:是抽象化的子类,实现父类的业务方法,并通过组合调用实现角色的业务方法。
(3)实现化角色:定义实现化角色的接口,供扩展抽象角色使用。
(4)具体实现化角色:给出实现化角色的具体实现。
该模式的结构图如下所示:
所以,根据桥接模式我们重新给出设计关系,如下所示:
这里需要理解下,抽象部分和它的实现部分分离,并不是说让抽象类和具体的实现类分离,这样没有任何意义,抽象部分指的是多个实体之间存在的共同的概念性联系,实现部分指的是在将这些抽象化的概念抽离出去后,软件的实现。我们可以选择软件系统中任一维度作为抽象,而另一维度给出实现,比如将手机的品牌作为抽象,将功能作为实现部分。桥接模式指在一个软件系统的抽象化和实现化之间使用组合/聚合关系而不是继承关系,从而使两者可以相对独立地变化
- 桥接模式的适用场景
(1)当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时。
(2)当一个系统不希望使用继承或者使用多层次继承使得类的个数剧增时。
(3)当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时。