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;
}
相关推荐
高晶12 小时前
SPMI 控制器 RTL 设计与验证新手入门
设计模式·程序员·架构
geovindu21 小时前
rust:N-Barrier Pattern
开发语言·后端·设计模式·rust·屏障模式·并发型模式
顧棟21 小时前
OpenAPI 网关:鉴权 + 流量治理 一体化设计方案与实现
java·spring boot·设计模式
拆房老料1 天前
【第四部分:Agentic 智能体设计模式】17. Agent 路由模式详解:从意图识别到动态模型选择
java·设计模式·ai编程·策略模式
是2的10次方啊1 天前
设计模式与生活⑩:地铁没变,你换了个状态
设计模式
步行cgn2 天前
适配器设计模式:一个“翻译官”的故事
设计模式
扶尔魔ocy2 天前
【QT C++】常用设计模式
c++·设计模式
她说..2 天前
常见设计模式-观察者模式
java·spring boot·spring·观察者模式·设计模式
是2的10次方啊2 天前
设计模式与生活⑨:一碗胡辣汤,用不着认识十几种香料
设计模式
geovindu3 天前
rust: Semaphore Pattern
开发语言·后端·设计模式·rust·代理模式·企业级信号量模式·同步型模式