作用
适配器模式的作用是可以让不兼容的接口在一起工作
案例
假如现在有一台电脑和一台投影仪,现在需要把电脑和投影仪进行连接
在此基础上我们再假设,电脑只能连接VGA接口,而投影仪的种类繁多,有VGA接口、HAMI接口等多种种类。
那么问题是,如何使得不同种类接口的投影仪都可以连接到只有一种接口的电脑上
我们首先看相同的接口是如何连接的
首先创建VGA接口类和使用VGA接口类的投影仪(TV01)
class VGA
{
public:virtual void play()=0;
};//投影仪01,使用VGA接口播放视频
class TV01:public VGA{
public:void play()override{cout<<"TV01:使用VGA接口进行视频播放"<<endl;}
};
接下来我们创建电脑类,其中有一个播放视频的功能,且使用VGA接口进行播放
class Computer
{
public:virtual void videoPlay(VGA*)=0;
};class HwComputer:public Computer
{
public:void videoPlay(VGA* vgaPtr)override{vgaPtr->play();}
};
接下来,我们在测试代码中使用VGA接口将投影仪TV01和电脑连接起来
void test()
{unique_ptr<Computer> hwPtr(new HwComputer());hwPtr->videoPlay(new TV01());}
编译运行,结果如下:
现在我们增加一个新的接口
class HDMI
{virtual void play()=0;
};class TV02:public HDMI
{
public:void play()override{cout<<"TV02:使用HDMI接口进行视频播放"<<endl;}
};
我们知道,电脑的视频播放接口是VGA,如下所示
virtual void videoPlay(VGA*)=0;
那么如果我们要想使用HDMI接口,可以有两种办法:
- 重新为电脑定义一个视频播放的方法,把接口更换为HDMI
- 使用适配器模式,将HDMI接口转换为VGA接口
具体如何如何使用适配器模式进行接口转换呢?我们看以下代码
class VGAtoHDMIAdapter : public VGA {
public:VGAtoHDMIAdapter(HDMI* p) : _hdmiPtr(p) {};void play() override {_hdmiPtr->play();}
private:HDMI* _hdmiPtr;
};
观察以上代码,在这个适配器类(VGAtoHDMIAdapter)中,我们将VGA类作为父类,这样由于适配器类作为VGA的子类,因此可以将一个VGAtoHDMIAdapter对象作为参数传递给电脑的videoPlay函数,因为videoPlay中的VGA类型参数作为父类指针,可以指向作为VGAtoHDMIAdapter的子类对象。
因此,基于这种特性,我们就完全可以在VGAtoHDMIAdapter类中使用HDMI对象
测试代码如下:
void test()
{unique_ptr<Computer> hwPtr(new HwComputer());//使用VGA接口的投影仪进行视频播放hwPtr->videoPlay(new TV01());//使用HDMI接口的投影仪进行视频播放hwPtr->videoPlay(new VGAtoHDMIAdapter(new TV02()));
}
完整代码如下:
#include<iostream>
#include<memory>
using namespace std;class VGA {
public:virtual void play() = 0;
};class TV01 : public VGA {
public:void play() override {cout << "TV01:使用VGA接口进行视频播放" << endl;}
};class HDMI {
public:virtual void play() = 0;
};class TV02 : public HDMI {
public:void play() override {cout << "TV02:使用HDMI接口进行视频播放" << endl;}
};class VGAtoHDMIAdapter : public VGA {
public:VGAtoHDMIAdapter(HDMI* p) : _hdmiPtr(p) {};void play() override {_hdmiPtr->play();}
private:HDMI* _hdmiPtr;
};class Computer
{
public:virtual void videoPlay(VGA*)=0;
};class HwComputer:public Computer
{
public:void videoPlay(VGA* vgaPtr)override{vgaPtr->play();}
};void test()
{unique_ptr<Computer> hwPtr(new HwComputer());//使用VGA接口的投影仪进行视频播放hwPtr->videoPlay(new TV01());//使用HDMI接口的投影仪进行视频播放hwPtr->videoPlay(new VGAtoHDMIAdapter(new TV02()));
}int main(){test();return 0;
}