C++设计模式-Adapter适配器模式
2016-07-04 15:03
337 查看
Adapter适配器模式
作用:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
分为类适配器模式和对象适配器模式。
系统的数据和行为都正确,但接口不符时,我们应该考虑使用适配器,目的是使控制范围之外的一个原有对象与某个接口匹配。适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况。
想使用一个已经存在的类,但如果它的接口,也就是它的方法和你的要求不相同时,就应该考虑用适配器模式。
比如购买的第三方开发组件,该组件接口与我们自己系统的接口不相同,或者由于某种原因无法直接调用该组件,可以考虑适配器。
UML图如下:
图1:类模式适配器
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/04/75b6f98ec29f29a38a91cb5ed8eac77a)
图2:对象模式适配器
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/04/c929d74fa081ec6f328da5a5cb6cfda8)
代码如下:
Adapter.h
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
Adapter.cpp
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
main.cpp
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
在Adapter模式的两种模式中,有一个很重要的概念就是接口继承和实现继承的区别和联系。接口继承和实现继承是面向对象领域的两个重要的概念,接口继承指的是通过继承,子类获得了父类的接口,而实现继承指的是通过继承子类获得了父类的实现(并不统共接口)。在C++中的public继承既是接口继承又是实现继承,因为子类在继承了父类后既可以对外提供父类中的接口操作,又可以获得父类的接口实现。当然我们可以通过一定的方式和技术模拟单独的接口继承和实现继承,例如我们可以通过private继承获得实现继承的效果(private继承后,父类中的接口都变为private,当然只能是实现继承了。),通过纯抽象基类模拟接口继承的效果,但是在C++中pure
virtual function也可以提供默认实现,因此这是不纯正的接口继承,但是在Java中我们可以interface来获得真正的接口继承了。
作用:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
分为类适配器模式和对象适配器模式。
系统的数据和行为都正确,但接口不符时,我们应该考虑使用适配器,目的是使控制范围之外的一个原有对象与某个接口匹配。适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况。
想使用一个已经存在的类,但如果它的接口,也就是它的方法和你的要求不相同时,就应该考虑用适配器模式。
比如购买的第三方开发组件,该组件接口与我们自己系统的接口不相同,或者由于某种原因无法直接调用该组件,可以考虑适配器。
UML图如下:
图1:类模式适配器
图2:对象模式适配器
代码如下:
Adapter.h
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
1 #ifndef _ADAPTER_H_ 2 #define _ADAPTER_H_ 3 4 //目标接口类,客户需要的接口 5 class Target 6 { 7 public: 8 Target(); 9 virtual ~Target(); 10 virtual void Request();//定义标准接口 11 }; 12 13 //需要适配的类 14 class Adaptee 15 { 16 public: 17 Adaptee(); 18 ~Adaptee(); 19 void SpecificRequest(); 20 }; 21 22 //类模式,适配器类,通过public继承获得接口继承的效果,通过private继承获得实现继承的效果 23 class Adapter:public Target,private Adaptee 24 { 25 public: 26 Adapter(); 27 ~Adapter(); 28 virtual void Request();//实现Target定义的Request接口 29 }; 30 31 //对象模式,适配器类,继承Target类,采用组合的方式实现Adaptee的复用 32 class Adapter1:public Target 33 { 34 public: 35 Adapter1(Adaptee* adaptee); 36 Adapter1(); 37 ~Adapter1(); 38 virtual void Request();//实现Target定义的Request接口 39 private: 40 Adaptee* _adaptee; 41 }; 42 #endif
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
Adapter.cpp
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
1 #include "Adapter.h" 2 #include <iostream> 3 4 using namespace std; 5 6 Target::Target() 7 {} 8 9 Target::~Target() 10 {} 11 12 void Target::Request() 13 { 14 cout << "Target::Request()" << endl; 15 } 16 17 Adaptee::Adaptee() 18 { 19 } 20 21 Adaptee::~Adaptee() 22 { 23 } 24 25 void Adaptee::SpecificRequest() 26 { 27 cout << "Adaptee::SpecificRequest()" << endl; 28 } 29 30 //类模式的Adapter 31 Adapter::Adapter() 32 { 33 } 34 35 Adapter::~Adapter() 36 { 37 } 38 39 void Adapter::Request() 40 { 41 cout << "Adapter::Request()" << endl; 42 this->SpecificRequest(); 43 cout << "----------------------------" <<endl; 44 } 45 46 //对象模式的Adapter 47 Adapter1::Adapter1():_adaptee(new Adaptee) 48 { 49 } 50 51 Adapter1::Adapter1(Adaptee* _adaptee) 52 { 53 this->_adaptee = _adaptee; 54 } 55 56 Adapter1::~Adapter1() 57 { 58 } 59 60 void Adapter1::Request() 61 { 62 cout << "Adapter1::Request()" << endl; 63 this->_adaptee->SpecificRequest(); 64 cout << "----------------------------" <<endl; 65 }
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
main.cpp
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
1 #include "Adapter.h" 2 3 int main() 4 { 5 //类模式Adapter 6 Target* pTarget = new Adapter(); 7 pTarget->Request(); 8 9 //对象模式Adapter1 10 Adaptee* ade = new Adaptee(); 11 Target* pTarget1= new Adapter1(ade); 12 pTarget1->Request(); 13 14 //对象模式Adapter2 15 Target* pTarget2 = new Adapter1(); 16 pTarget2->Request(); 17 18 return 0; 19 }
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
在Adapter模式的两种模式中,有一个很重要的概念就是接口继承和实现继承的区别和联系。接口继承和实现继承是面向对象领域的两个重要的概念,接口继承指的是通过继承,子类获得了父类的接口,而实现继承指的是通过继承子类获得了父类的实现(并不统共接口)。在C++中的public继承既是接口继承又是实现继承,因为子类在继承了父类后既可以对外提供父类中的接口操作,又可以获得父类的接口实现。当然我们可以通过一定的方式和技术模拟单独的接口继承和实现继承,例如我们可以通过private继承获得实现继承的效果(private继承后,父类中的接口都变为private,当然只能是实现继承了。),通过纯抽象基类模拟接口继承的效果,但是在C++中pure
virtual function也可以提供默认实现,因此这是不纯正的接口继承,但是在Java中我们可以interface来获得真正的接口继承了。
相关文章推荐
- Android Native 绘图方法
- PostgreSQL教程(三):表的继承和分区表详解
- C#中struct和class的区别详解
- Lua面向对象之类和继承浅析
- 浅析Ruby中继承和消息的相关知识
- VBS ArrayList Class vbs中的数组类
- 大家看了就明白了css样式中类class与标识id选择符的区别小结
- 设计引导--一个鸭子游戏引发的设计理念(多态,继承,抽象,接口,策略者模式)
- C++实现不能被继承的类实例分析
- C# 面向对象三大特性:封装、继承、多态
- PHP类的封装与继承详解
- 深入了解PHP类Class的概念
- js继承 Base类的源码解析
- jquery 表单验证之通过 class验证表单不为空
- Javascript 面向对象 继承
- JavaScript 继承使用分析
- Javascript面向对象编程(二) 构造函数的继承
- Javascript中的几种继承方式对比分析
- javascript面向对象之Javascript 继承
- JavaScript 对象、函数和继承