c++设计模式之适配器模式

作用

适配器模式的作用是可以让不兼容的接口在一起工作

案例

假如现在有一台电脑和一台投影仪 ,现在需要把电脑和投影仪进行连接

在此基础上我们再假设,电脑只能连接VGA接口 ,而投影仪的种类繁多,有VGA接口、HAMI接口等多种种类。

那么问题是,如何使得不同种类接口的投影仪都可以连接到只有一种接口的电脑上

我们首先看相同的接口是如何连接的

首先创建VGA接口类和使用VGA接口类的投影仪(TV01)

cpp 复制代码
class  VGA
{
public:
    virtual void play()=0;
};

//投影仪01,使用VGA接口播放视频
class TV01:public VGA{
public:
    void play()override
    {
        cout<<"TV01:使用VGA接口进行视频播放"<<endl;
    }
};

接下来我们创建电脑类,其中有一个播放视频的功能,且使用VGA接口进行播放

cpp 复制代码
class Computer
{
public:
    virtual void videoPlay(VGA*)=0;
};

class HwComputer:public Computer
{
public:
    void videoPlay(VGA* vgaPtr)override
    {
        vgaPtr->play();
    }
};

接下来,我们在测试代码中使用VGA接口将投影仪TV01和电脑连接起来

cpp 复制代码
void test()
{
    unique_ptr<Computer> hwPtr(new HwComputer());
    hwPtr->videoPlay(new TV01());

}

编译运行,结果如下:

现在我们增加一个新的接口

cpp 复制代码
class HDMI
{
    virtual void play()=0;
};

class TV02:public HDMI
{
public:
    void play()override
    {
        cout<<"TV02:使用HDMI接口进行视频播放"<<endl;
    }
};

我们知道,电脑的视频播放接口是VGA,如下所示

cpp 复制代码
virtual void videoPlay(VGA*)=0;

那么如果我们要想使用HDMI接口,可以有两种办法:

  • 重新为电脑定义一个视频播放的方法,把接口更换为HDMI
  • 使用适配器模式,将HDMI接口转换为VGA接口

具体如何如何使用适配器模式进行接口转换呢?我们看以下代码

cpp 复制代码
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对象

测试代码如下:

cpp 复制代码
void test()
{
    unique_ptr<Computer> hwPtr(new HwComputer());

    //使用VGA接口的投影仪进行视频播放
    hwPtr->videoPlay(new TV01());
    //使用HDMI接口的投影仪进行视频播放
    hwPtr->videoPlay(new VGAtoHDMIAdapter(new TV02()));
}

完整代码如下:

cpp 复制代码
#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;
}
相关推荐
是2的10次方啊10 分钟前
🚀 Spring设计模式大揭秘:23种模式藏在你每天在用的框架里
设计模式
东北南西14 分钟前
设计模式-单例模式
前端·javascript·单例模式·设计模式
快乐非自愿2 小时前
掌握设计模式--命令模式
设计模式·命令模式
我希望的一路生花11 小时前
Nik Collection 6.2全新版Nik降噪锐化调色PS/LR插件
人工智能·计算机视觉·设计模式·stable diffusion·aigc
东北南西16 小时前
设计模式-工厂模式
前端·设计模式
JohnYan17 小时前
工作笔记 - 改进的单例应用
javascript·设计模式·bun
郝学胜-神的一滴19 小时前
使用C++11改进工厂方法模式:支持运行时配置的增强实现
开发语言·c++·程序人生·设计模式
Leo来编程19 小时前
设计模式3-模板方法模式
设计模式·模板方法模式
Leo来编程2 天前
设计模式1-单例模式
单例模式·设计模式
危险库2 天前
单例模式:确保一个类只有一个实例【设计模式】
javascript·单例模式·设计模式