c++设计模式---- Bridge(桥接模式)
2015-09-13 22:13
639 查看
什么是桥接模式:
在GOF的《设计模式:可复用面向对象软件的基础》一书中对桥接模式是这样说的:将抽象部分和它的实现部分分离,使它们都可以独立的变化。简单粗暴的说,就是抽象对外提供调用的接口;对外隐瞒实现部分,在抽象中引用实现部分,从而实现抽象对实现部分的调用,而抽象中引用的实现部分可以在今后的开发过程中,切换成别的实现部分。
来看一个例子:
有一台电脑需要装系统,这条电脑上可以装Windows、linux、centos、苹果系统等等。我们的抽象类是电脑,实现类是由各种操作系统组成的。
实现代码:
如果我们还有扩充这个例子,我们不止有联想电脑,还有戴尔、华硕、惠普等等电脑,这些电脑同样可以安装Windows、linux、iOS等等系统,所以我们只需要添加一个新的电脑类而不用修改原先类就可以达到客户的要求,这就是桥接模式的好处。
总结一下桥接模式:
意图:
将抽象部分与它的实现部分分离,使它们都可以独立地变化。
适用性:
你不希望在抽象和它的实现部分之间有一个固定的绑定关系。例如这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换。
类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这时Bridge 模式使你可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。
对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译。
(C++)你想对客户完全隐藏抽象的实现部分。在C++中,类的表示在类接口中是可见的。
有许多类要生成。这样一种类层次结构说明你必须将一个对象分解成两个部分。Rumbaugh 称这种类层次结构为“嵌套的普化”(nested generalizations )。
你想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不知道这一点。一个简单的例子便是Coplien 的String 类[ Cop92 ],在这个类中多个对象可以共享同一个字符串表示(StringRep )。
Abstraction类定义了抽象类的接口,并且维护一个指向Implementor实现类的指针;
RefineAbstraction类扩充了Abstraction类的接口;
Implementor类定义了实现类的接口,这个接口不一定要与Abstraction的接口完全一致;实际上,这两个接口可以完全不同;
ConcreteImplementor类实现了Implementor定义的接口。
实现代买如下:
#include <iostream>
using namespace std;
class Implementor
{
public:
virtual void OperationImpl() = 0;
};
class ConcreteImpementorA : public Implementor
{
public:
void OperationImpl()
{
cout << "OperationImpl A" << endl;
}
};
class ConcreteImpementorB : public Implementor
{
public:
void OperationImpl()
{
cout << "OperationImpl B" << endl;
}
};
class Abstraction
{
public:
Abstraction(Implementor *pImpl) : m_pImpl(pImpl){}
virtual void Operation() = 0;
protected:
Implementor *m_pImpl;
};
class RedfinedAbstraction : public Abstraction
{
public:
RedfinedAbstraction(Implementor *pImpl) : Abstraction(pImpl){}
void Operation()
{
m_pImpl->OperationImpl();
}
};
int main(int argc, char *argv[])
{
Implementor *pImplObj1 = new ConcreteImpementorA();
Implementor *pImplObj2 = new ConcreteImpementorB();
Abstraction *pAbsObj1 = new RedfinedAbstraction(pImplObj2);
pAbsObj1->Operation();
Abstraction *pAbsObj2 = new RedfinedAbstraction(pImplObj2);
pAbsObj2->Operation();
delete pImplObj1;
pImplObj1 = NULL;
delete pAbsObj1;
pAbsObj1 = NULL;
delete pAbsObj2;
pAbsObj2 = NULL;
return 0;
}
桥接模式使得抽象和实现进行了分离,抽象不用依赖于实现,让抽象和实现部分各自修改起来都很方便,使用组合(就是Abstraction类中包含了Implementor)的方式,降低了耦合度,同时也有助于分层,从而产生更好的结构化系统。通过实际的项目经验,使用了桥接模式的代码,对以后的扩展有很大的帮助。
在GOF的《设计模式:可复用面向对象软件的基础》一书中对桥接模式是这样说的:将抽象部分和它的实现部分分离,使它们都可以独立的变化。简单粗暴的说,就是抽象对外提供调用的接口;对外隐瞒实现部分,在抽象中引用实现部分,从而实现抽象对实现部分的调用,而抽象中引用的实现部分可以在今后的开发过程中,切换成别的实现部分。
来看一个例子:
有一台电脑需要装系统,这条电脑上可以装Windows、linux、centos、苹果系统等等。我们的抽象类是电脑,实现类是由各种操作系统组成的。
实现代码:
#include <iostream> using namespace std; //操作系统 class OS { public: virtual void InstallOS_Imp() {} }; class WindowOS : public OS { public: void InstallOS_Imp() { cout << "安装Window操作系统" << endl; } }; class LinuxOS : public OS { public: void InstallOS_Imp() { cout << "安装Linux操作系统" << endl; } }; class UnixOS : public OS { public: void InstallOS_Imp() { cout << "安装Unix操作系统" << endl; } }; //计算机 class Computer { public: virtual void InstallOS(OS *os) {} }; class LenovoComputer : public Computer { public: void InstallOS(OS *os) { os->InstallOS_Imp(); } }; int main() { OS* os1 = new WindowOS(); OS* os2 = new LinuxOS(); Computer *lianxiang = new LenovoComputer(); lianxiang->InstallOS(os1); lianxiang->InstallOS(os2); return 0; }
如果我们还有扩充这个例子,我们不止有联想电脑,还有戴尔、华硕、惠普等等电脑,这些电脑同样可以安装Windows、linux、iOS等等系统,所以我们只需要添加一个新的电脑类而不用修改原先类就可以达到客户的要求,这就是桥接模式的好处。
总结一下桥接模式:
意图:
将抽象部分与它的实现部分分离,使它们都可以独立地变化。
适用性:
你不希望在抽象和它的实现部分之间有一个固定的绑定关系。例如这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换。
类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这时Bridge 模式使你可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。
对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译。
(C++)你想对客户完全隐藏抽象的实现部分。在C++中,类的表示在类接口中是可见的。
有许多类要生成。这样一种类层次结构说明你必须将一个对象分解成两个部分。Rumbaugh 称这种类层次结构为“嵌套的普化”(nested generalizations )。
你想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不知道这一点。一个简单的例子便是Coplien 的String 类[ Cop92 ],在这个类中多个对象可以共享同一个字符串表示(StringRep )。
Abstraction类定义了抽象类的接口,并且维护一个指向Implementor实现类的指针;
RefineAbstraction类扩充了Abstraction类的接口;
Implementor类定义了实现类的接口,这个接口不一定要与Abstraction的接口完全一致;实际上,这两个接口可以完全不同;
ConcreteImplementor类实现了Implementor定义的接口。
实现代买如下:
#include <iostream>
using namespace std;
class Implementor
{
public:
virtual void OperationImpl() = 0;
};
class ConcreteImpementorA : public Implementor
{
public:
void OperationImpl()
{
cout << "OperationImpl A" << endl;
}
};
class ConcreteImpementorB : public Implementor
{
public:
void OperationImpl()
{
cout << "OperationImpl B" << endl;
}
};
class Abstraction
{
public:
Abstraction(Implementor *pImpl) : m_pImpl(pImpl){}
virtual void Operation() = 0;
protected:
Implementor *m_pImpl;
};
class RedfinedAbstraction : public Abstraction
{
public:
RedfinedAbstraction(Implementor *pImpl) : Abstraction(pImpl){}
void Operation()
{
m_pImpl->OperationImpl();
}
};
int main(int argc, char *argv[])
{
Implementor *pImplObj1 = new ConcreteImpementorA();
Implementor *pImplObj2 = new ConcreteImpementorB();
Abstraction *pAbsObj1 = new RedfinedAbstraction(pImplObj2);
pAbsObj1->Operation();
Abstraction *pAbsObj2 = new RedfinedAbstraction(pImplObj2);
pAbsObj2->Operation();
delete pImplObj1;
pImplObj1 = NULL;
delete pAbsObj1;
pAbsObj1 = NULL;
delete pAbsObj2;
pAbsObj2 = NULL;
return 0;
}
桥接模式使得抽象和实现进行了分离,抽象不用依赖于实现,让抽象和实现部分各自修改起来都很方便,使用组合(就是Abstraction类中包含了Implementor)的方式,降低了耦合度,同时也有助于分层,从而产生更好的结构化系统。通过实际的项目经验,使用了桥接模式的代码,对以后的扩展有很大的帮助。
相关文章推荐
- c++11——改进容器性能
- 【LeetCode从零单刷】Lowest Common Ancestor of a Binary Search Tree
- 实现跨平台的C++线程库
- 深入理解C语言类型转换
- C++模板
- c++11——move/forward
- 【LeetCode从零单刷】Convert Sorted Array to Binary Search Tree
- c++字符串操作函数
- C++基础知识总结--指针
- C++ STL中的关于堆的函数
- 实现C++实用的时间库
- 【LeetCode从零单刷】Single Number III
- C语言实现单链表-01版
- Effective C++ —— 实现(五)
- C++模板的一些巧妙功能
- C++模板的一些巧妙功能
- C语言初步接触
- 设计模式C++实现(8)——代理模式
- 设计模式C++实现(7)——外观模式、组合模式
- 设计模式C++实现(6)——建造者模式(Builder)