一 简介
桥接模式,将抽象部分与它的实现部分分离,使它们都可以独立地变化。这里说的实现分离,并不是说然抽象类与派生类分离,这没有任何意义。实现指的是抽象类和它的派生类用来实现自己的对象。
二 UML图
结合上图理解一下其定义。抽象部分指的是Abstraction或者RefinedAbstraction。实现部分指的是Implementor。以为抽象部分得实现有多种变化,为了减少耦合,所以把实现部分得变化封装起来,通过组合得方式实现。这就是定义中说得将抽象部分与它得实现部分分离。而定义中说得实现指得是抽象类和它得派生类用来实现自己得对象就是对变化封装后得类,即Implementor。
三 例子
//软件基类
class Soft
{
public:
virtual void run() = 0;
};
//游戏软件
class GameSoft :public Soft
{
public:
void run()
{
cout << "游戏软件" << endl;
}
};
//音乐软件
class MusicSof :public Soft
{
public:
void run()
{
cout << "音乐软件" << endl;
}
};
//操作系统
class System
{
public:
virtual ~System()
{
if(m_soft)
delete m_soft;
};
//安装软件
void loadSoft(Soft* soft)
{
if (m_soft)
delete m_soft;
m_soft = soft;
}
//运行软件
virtual void run() = 0;
protected:
Soft* m_soft = NULL;;
};
//Windows
class Windows :public System
{
public:
virtual void run()
{
cout << "Windows 上运行了";
m_soft->run();
}
};
//Linux
class Linux :public System
{
public:
virtual void run()
{
cout << "Linux 上运行了";
m_soft->run();
}
};
int main()
{
System* windows = new Windows();
windows->loadSoft(new MusicSof());
windows->run();
windows->loadSoft(new GameSoft());
windows->run();
delete windows;
System* linux = new Linux();
linux->loadSoft(new MusicSof());
linux->run();
linux->loadSoft(new GameSoft());
linux->run();
delete linux;
getchar();
return 0;
}
四 优缺点
优点:
- 将实现抽离出来,再实现抽象,使得对象的具体实现依赖于抽象,满足了依赖倒转原则。
- 将可以共享的变化部分,抽离出来,减少了代码的重复信息。
- 对象的具体实现可以更加灵活,可以满足多个因素变化的要求。
缺点:
- 客户必须知道选择哪一种类型的实现。
五 Bridge模式使用总结:
Bridge模式将抽象和实现分别独立实现,在代码中就是Abstraction类和AbstractionImplement类。
使用组合(委托)的方式将抽象和实现彻底地解耦,这样的好处是抽象和实现可以分别独立地变化,系统的耦合性也得到了很好的降低。
GoF的那句话中的“实现”该怎么去理解:“实现”特别是和“抽象”放在一起的时候我们“默认”的理解是“实现”就是“抽象”的具体子类的实现,但是这里GoF所谓的“实现”的含义不是指抽象基类的具体子类对抽象基类中虚函数(接口)的实现,是和继承结合在一起的。
而这里的“实现”的含义指的是怎么去实现用户的需求,并且指的是通过组合(委托)的方式实现的,因此这里的实现不是指的继承基类、实现基类接口,而是指的是通过对象组合实现用户的需求。
实际上上面使用Bridge模式和使用带来问题方式的解决方案的根本区别在于是通过继承还是通过组合的方式去实现一个功能需求。