(本博客旨在个人总结回顾)
1、详情:
桥接模式:将抽象部分与它实现部分分离,使它们都可以独立地变化。
说明:
主要解决:在有多种可能会变化的情况下,用继承会造成类爆炸问题,扩展起来不灵活。
何时使用:实现系统可能有多个角度分类,每一种角度都可能变化。
如何解决:把这种多角度分类分离出来,让它们独立变化,减少它们之间耦合。
关键代码:抽象类依赖实现类。
优点: ①抽象和实现的分离。 ②优秀的扩展能力。 ③实现细节对客户透明。
缺点:桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
使用场景:
①如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
②对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
③一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
注意事项:对于两个独立变化的维度,使用桥接模式再适合不过了。
2、应用实例:
手机(品牌和软件)实例。(手机是抽象部分,手机上的软件是它的实现部分,不同品牌,不同软件就是它们各自的变化)
3.1、UML类图:
3.2、例子源码
stdafx.h
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <iostream>
using namespace std;
// TODO: 在此处引用程序需要的其他头文件
抽象部分:
Handset.h(抽象类手机)
#pragma once
#include "HandsetSoft.h"
#include <list>
class Handset
{
public:
Handset();
virtual ~Handset();
public:
void SetHandsetSoft(HandsetSoft* pHandsetSoft);
virtual void Run() = 0;
protected:
std::list<HandsetSoft*> m_listSoft;
};
Handset.cpp
#include "stdafx.h"
#include "Handset.h"
Handset::Handset()
{
}
Handset::~Handset()
{
for (std::list<HandsetSoft*>::iterator it = m_listSoft.begin(); it != m_listSoft.end(); it++)
{
delete *it;
}
m_listSoft.clear();
}
void Handset::SetHandsetSoft(HandsetSoft* pHandsetSoft)
{
m_listSoft.push_back(pHandsetSoft);
}
HandsetBrandN.h
#pragma once
#include "Handset.h"
class HandsetBrandN :
public Handset
{
public:
HandsetBrandN();
~HandsetBrandN();
public:
void Run();
};
HandsetBrandN.cpp
#include "stdafx.h"
#include "HandsetBrandN.h"
HandsetBrandN::HandsetBrandN()
{
}
HandsetBrandN::~HandsetBrandN()
{
}
void HandsetBrandN::Run()
{
for (std::list<HandsetSoft*>::iterator it = m_listSoft.begin(); it != m_listSoft.end(); it++)
{
cout << "+NN+";
(*it)->RunImp();
}
}
HandsetBrandM.h
#pragma once
#include "Handset.h"
class HandsetBrandM :
public Handset
{
public:
HandsetBrandM();
~HandsetBrandM();
public:
void Run();
};
HandsetBrandM.cpp
#include "stdafx.h"
#include "HandsetBrandM.h"
HandsetBrandM::HandsetBrandM()
{
}
HandsetBrandM::~HandsetBrandM()
{
}
void HandsetBrandM::Run()
{
for (std::list<HandsetSoft*>::iterator it = m_listSoft.begin(); it != m_listSoft.end(); it++)
{
cout << "+MM+";
(*it)->RunImp();
}
}
实现部分:
HandsetSoft.h(实现类软件)
#pragma once
#include "HandsetSoft.h"
class Handset
{
public:
Handset();
virtual ~Handset();
public:
void SetHandsetSoft(HandsetSoft* pHandsetSoft);
virtual void Run() = 0;
protected:
HandsetSoft* m_pHandsetSoft;
};
HandsetSoft.cpp
#include "stdafx.h"
#include "HandsetSoft.h"
HandsetSoft::HandsetSoft()
{
}
HandsetSoft::~HandsetSoft()
{
}
HandsetGame.h
#pragma once
#include "HandsetSoft.h"
class HandsetGame :
public HandsetSoft
{
public:
HandsetGame();
~HandsetGame();
public:
void RunImp();
};
HandsetGame.cpp
#include "stdafx.h"
#include "HandsetGame.h"
HandsetGame::HandsetGame()
{
}
HandsetGame::~HandsetGame()
{
}
void HandsetGame::RunImp()
{
cout << "运行手机游戏!" << endl;
}
HandsetAddressList.h
#pragma once
#include "HandsetSoft.h"
class HandsetAddressList :
public HandsetSoft
{
public:
HandsetAddressList();
~HandsetAddressList();
public:
void RunImp();
};
HandsetAddressList.cpp
#include "stdafx.h"
#include "HandsetAddressList.h"
HandsetAddressList::HandsetAddressList()
{
}
HandsetAddressList::~HandsetAddressList()
{
}
void HandsetAddressList::RunImp()
{
cout << "运行手机通讯录!" << endl;
}
调用代码:
BradgePatternMemo.cpp
// BridgePatternMemo.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "Handset.h"
#include "HandsetBrandN.h"
#include "HandsetBrandM.h"
#include "HandsetGame.h"
#include "HandsetAddressList.h"
int _tmain(int argc, _TCHAR* argv[])
{
Handset* pHandset = new HandsetBrandN();
pHandset->SetHandsetSoft(new HandsetGame());
pHandset->SetHandsetSoft(new HandsetAddressList());
pHandset->Run();
delete pHandset;
pHandset = NULL;
pHandset = new HandsetBrandM();
pHandset->SetHandsetSoft(new HandsetGame());
pHandset->SetHandsetSoft(new HandsetAddressList());
pHandset->Run();
delete pHandset;
pHandset = NULL;
system("pause");
return 0;
}
3.3、运行结果: