设计模式详解:Bridge(桥接模式)

Bridge 桥接模式

设计模式学习:概述

意图

将抽象部分与它的实现部分分离,使得二者都可以独立地变化。

别名:Handle/Body

当一个抽象机制有多个可能的实现时,我们通常采用继承来协调它们的关系。但是,这有时会带来硬编码不灵活的问题,Bridge机制可以解决因为继承导致的不灵活的毛病。

事实上,Bridge模式也是遵循了单一职责原则的指导:桥接模式将应用程序的业务功能具体实现解耦,也就是将抽象具体实现解耦,从而让位于不同功能维度的二者可以各自变化而不受影响。

站在稳定-变化的角度,Bridge模式解决的是在业务功能与具体实现的关系相对稳定的情况下,实现方式可能出现的变化

代码案例

考虑这样的一种情况:一个UI应用程序窗口,它可能拥有多种功能,比如打开文件,建立新窗口,关闭文件等等。但是为了获取更多的用户,甲方决定应当使该应用程序兼容多个平台(Windows、Linux、Mac)。如何解决这个问题?

最简单的想法如下:

Program WindowsProgram LinuxProgram MacProgram WriteFileWindows CloseFileWindows WriteFileLinux CloseFileLinux WriteFileMac CloseFileMac

针对每种平台,让它继承自Program抽象基类,并拥有符合自己平台的实现方式。

在这种情况下,我们将业务功能(这里只列举了开、关文件,实际上应该多得多)和抽象实现放在同一个类中进行描述。那么,在用户创建一个窗口时,就必须显示的指出是在怎么样的平台下,采用下面的方式进行创建:

Program* pr = new WindowsProgram();

如果你对Decorator设计模式够了解,那么你就已经可以发现这种设计的弊端了:两个发展方向不同的模块:应用功能和具体实现被硬编码到了一起。这会导致不灵活,以及可能的子类过多的情况。事实上,Bridge模式和Decorator模式是异曲同工的。

扫描二维码关注公众号,回复: 12717510 查看本文章

现在,我们试图将应用功能抽象和它的具体实现分离,于是有下面的类图:

Program ProgramImp* pl//多态指针 WriteFile CloseFile ProgramImp WindowsImp LinuxImp MacImp

如上图所示,左边的类树表明了应用抽象,而右边是它的具体实现,它们中间的**“桥”**,也就是位于Program抽象基类中的ProgramImp*多态指针。

下面列出WriteFile的具体实现,你大概就能理解这样做的原因了

void WriteFile(String filename)
{
    
    
    //pl是ProgramImp多态指针
    pl->open(filename);
    ...
    pl->write(...);
    ...
    pl->close(filename);
}

在调用WriteFile时,系统根据多态指针pl具体的指向选择调用哪个平台下的open、write、close函数,将编译时多态转换为运行时(Runtime),大大提高了灵活性。

由于之前所说,应用抽象与具体实现是两个不同的发展维度,因此,可以看到,这里的WriteFile函数流程完全不受平台实现的影响,只在具体细节上调用了Imp类中的函数。因此,如果想将程序由Windows移植到Mac,只需要如下更改:

WriteFile* p = new WriteFile(new WindowsImp());//原本是Windows下
p->pl = new MacImp();//只需更改多态指针指向

多么一目了然!

解释

之所以用了上面这个例子来解释,也是因为几乎所有跨平台的应用程序,都是使用Bridge模式来完成对不同操作系统的兼容的。

Bridge在本质上与Decorator异曲同工,Decorator解决的是独立功能的组合问题,而Bridge解决的是抽象与具体实现的分别变化。它们都采用组合一个多态基类指针的方式来实现运行时多态,从而增加了程序的灵活性,并大大减少了子类的数目。

用接口编程的思想来理解它,Bridge模式使得实现和接口分离,使得一个对象甚至可以在运行时刻改变它的实现,这对Java程序员来讲或许更加熟悉。要注意的一点是:Abstraction和Implementation是一对一的!

更重要的是,Bridge模式可以让功能抽象和具体实现进行独立扩充。比如,可以在不改变抽象的情况下,为WindowImp增加一个Mobile子类,使得它兼容移动设备。或者,为程序添加一个功能,而不需要对具体实现做任何修改。

Bridge的使用重点在于,功能抽象和具体实现的基类都应当是稳定的,否则该模式就不再适用。因此在编写抽象和具体实现的基类时,要尤其考虑这两者在未来是否会有大的变化。

总结

设计模式 Bridge(桥接模式)
稳定点: 功能抽象与具体实现的关系:具体实现应当提供给抽象的函数。
变化点: 抽象功能和实现方式。
效果: 使得抽象部分和实现部分能够独立地变化。
特点: 抽象与实现是一对一的。
Abstraction Implementor* imp RefinedAbstraction Implementor virtual operation ConcreteImpA ConcreteImpB

2021.2.4 转载请标明出处

猜你喜欢

转载自blog.csdn.net/natrick/article/details/113694171