c++桥接模式
2021/10/3 11:10:04
本文主要是介绍c++桥接模式,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
范例一:
#include <iostream> #include <thread> #ifdef _DEBUG //只在Debug(调试)模式下 #ifndef DEBUG_NEW #define DEBUG_NEW new(_NORMAL_BLOCK,__FILE__,__LINE__) //重新定义new运算符 #define new DEBUG_NEW #endif #endif using namespace std; //#pragma warning(disable : 4996) class Image { public: virtual ~Image() {}; void draw(const char *pfilename) { int len = 1; char* data = parsefile(pfilename, len); /*下面用于显示读取到的图片格式,不同的操作系统显示不一样*/ if(len > 0) { //模拟代码 cout << "显示缓冲区中的图像数据" << endl; } } /*该函数用于读取指定格式(比如png,jpg,bmp)*到一个缓存当中 不同格式的图片读取方式不一样,并且读取方式与操作系统平台无关*/ virtual char* parsefile(const char* pfilename, int &len) = 0; }; class Image_png :public Image { public: char* parsefile(const char* pfilename, int& len) { //...模拟代码 cout << "开始分析png文件中的数据并将分析结果放到缓存中\n"; return nullptr; } }; class Image_jpg :public Image { public: char* parsefile(const char* pfilename, int& len) { //...模拟代码 cout << "开始分析jpg文件中的数据并将分析结果放到缓存中\n"; return nullptr; } }; class Image_bmp :public Image { public: char* parsefile(const char* pfilename, int& len) { //...模拟代码 cout << "开始分析bmp文件中的数据并将分析结果放到缓存中\n"; return nullptr; } }; int main() { _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); Image* p = new Image_png(); p->draw("c:\\a.png"); return 0; }
像以上的范例当中,如果再引入不同的操作系统的话,他们之间的关系可能会变成如下所示。
缺点就是由于类与类之间的这种继承的关系会引入很多子类对象,后面再需要扩展的时候就不好维护了。
下面我们根据范例一进行改造一下,把类与类之间的关系有继承关系改成委托与组合关系。
委托与组合关系的话,他们采用的不是继承关系,而是在一个类当中包含另一个类的指针变量。
范例二:
#include <iostream> #include <thread> using namespace std; class ImageOS { public: virtual void draw(char* pData, int iLen) = 0; virtual ~ImageOS() {} }; class ImageOS_Windows :public ImageOS { public: virtual void draw(char* pData, int iLen) { //模拟代码 cout << "在Windows操作系统下显示缓冲区中的图像数据\n" << endl; } }; class ImageOS_Linux :public ImageOS { public: virtual void draw(char* pData, int iLen) { //模拟代码 cout << "在Linux操作系统下显示缓冲区中的图像数据\n" << endl; } }; class ImageOS_Mac :public ImageOS { public: virtual void draw(char* pData, int iLen) { //模拟代码 cout << "在Mac操作系统下显示缓冲区中的图像数据\n" << endl; } }; class ImageFormat { public: ImageFormat(ImageOS* pimgos) :m_pImgOS(pimgos) {} /*纯虚函数,有子类定义实现部分*/ virtual void parsefile(const char* pfilename) = 0; virtual ~ImageFormat() {} protected: ImageOS* m_pImgOS; //委托 }; class Image_png:public ImageFormat { public: Image_png(ImageOS* pimgos) :ImageFormat(pimgos){} void parsefile(const char* pfilename) { //模拟代码 cout << "读取png格式的内容到缓冲区当中\n" << endl; char* p = nullptr; int len = 0; m_pImgOS->draw(p, len); } }; class Image_jpg :public ImageFormat { public: Image_jpg(ImageOS* pimgos) :ImageFormat(pimgos) {} void parsefile(const char* pfilename) { //模拟代码 cout << "读取jpg格式的内容到缓冲区当中\n" << endl; char* p = nullptr; int len = 0; m_pImgOS->draw(p, len); } }; class Image_bmp :public ImageFormat { public: Image_bmp(ImageOS* pimgos) :ImageFormat(pimgos) {} void parsefile(const char* pfilename) { //模拟代码 cout << "读取bmp格式的内容到缓冲区当中\n" << endl; char* p = nullptr; int len = 0; m_pImgOS->draw(p, len); } }; int main() { _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); ImageOS* p_os = new ImageOS_Mac(); ImageFormat* p_format = new Image_bmp(p_os); p_format->parsefile("c:\\a.bmp"); delete p_os; delete p_format; return 0; }
如果要是再扩展一个新的操作系统,引入的子类对象是不是减少了?
引入桥接(Bridge)模式
不同维度的独立变化,才是能够顺利使用桥接模式的前提。
定义:将抽象部分与它的实现部分分离,使他们都可以独立地变化和扩展。
抽象部分:一般指业务功能,比如ImageFormat类。
实现部分:一般指具体平台实现,比如ImageOS类。
角色:
(a)Abstraction(抽象部分相关接口):ImageFormat类
(b)RefinedAbstraction(扩充抽象部分接口):Image_png、Image_jpg、Image_bmp类。
©Implementor(实现部分相关接口):ImageOS类
(d)ConcreteImplementor(实现部分具体类):ImageOS_Windows、ImageOS_Linux、ImageOS_Mac类。
这篇关于c++桥接模式的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享