设计模式之代理模式、适配器模式和外观模式
编写基于另一组类的包装器接口是一项常见的API设计任务,例如,你的工作可能是维护一个大型的遗留代码库,相比重构所有代码,你更愿意审计一个新的 ,更简洁的API,以隐藏所有的底层遗留代码;或者你可能已经编写了一个C++API,后来需要给特定客户提供C接口;或者你的API用到了一个第三方依赖库,你想让客户直接使用此库,但是又不想将此库直接暴露给客户。
创建包装器API的潜在副作用是影响性能,这主要因为额外增加的一级间接寻址以及存储包装层次状态带来的开销。但就上面提到的那些情而言,这么做可以创建质量更高的,更针对性的API,是物有所值。接下来将按照包装器层和原始接口的差异递增程度依次总结代理模式、适配器模式和外观模式。
1. 代理模式
1.1 类图
在上面的基础上添加代理的原始API共享的虚接口,这样做是为了更好地保存这两个API的同步,这么做的前提是你能够修改原始API。
1.2 代码实现
#pragma once #include <iostream> using namespace std; class IOriginal { public: IOriginal() { cout << "IOriginal Sturuct" << endl; } virtual ~IOriginal() { cout << "IOriginal Destruct" << endl; } virtual void DoSomething() = 0; }; class COriginal : public IOriginal { public: COriginal() { cout << "COriginal Sturuct" << endl; } ~COriginal() { cout << "COriginal Destruct" << endl; } void DoSomething() { cout << "COriginal DOSomething" << endl; } } class CProxy : public IOriginal { public: CProxy() { m_pOriginal = new COriginal(); cout << "CProxy Sturuct" << endl; } ~CProxy() { if (m_pOriginal != NULL) { delete COriginal; m_pOriginal = NULL; } cout << "CProxy Destruct" << endl; } void DoSomething() { m_pOriginal->DoSomething(); cout << "CProxy DOSomething" << endl; } private: COriginal *m_pOriginal; }
2. 适配器模式
适配器设计模式将一个类的接口转换为一个兼容的但不同的接口。与代理模式的相似之处是,适配器设计模式也是一个单一组件包装器,但适配器类和袁石磊的接口可以不相同。
2.1 类图
2.2 代码实现
#pragma once #include <iostream> using namespace std; class COriginal { public: COriginal() { cout << "COriginal Sturuct" << endl; } ~COriginal() { cout << "COriginal Destruct" << endl; } void DoSomethingA() { cout << "COriginal DOSomethingA" << endl; } } class CAdapter { public: CProxy() { m_pOriginal = new COriginal(); cout << "CProxy Sturuct" << endl; } ~CProxy() { if (m_pOriginal != NULL) { delete COriginal; m_pOriginal = NULL; } cout << "CProxy Destruct" << endl; } void fun() { //"......" m_pOriginal->DoSomethingA(); cout << "CProxy DOSomething" << endl; } private: COriginal *m_pOriginal; }
3. 外观模式
外观模式能够为一组类提供简化的接口。它实际上定义了一个更高层次的接口,以使得底层子系统更易于使用。
3.1 类图