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;
}
相关推荐
willow2 天前
Axios由浅入深
设计模式·axios
七月丶4 天前
别再手动凑 PR 了:这个 AI Skill 会按仓库习惯自动建分支、拆提交、提 PR
人工智能·设计模式·程序员
刀法如飞4 天前
从程序员到架构师:6大编程范式全解析与实践对比
设计模式·系统架构·编程范式
九狼4 天前
Flutter + Riverpod +MVI 架构下的现代状态管理
设计模式
静水流深_沧海一粟5 天前
04 | 别再写几十个参数的构造函数了——建造者模式
设计模式
StarkCoder5 天前
从UIKit到SwiftUI的迁移感悟:数据驱动的革命
设计模式
阿星AI工作室5 天前
给openclaw龙虾造了间像素办公室!实时看它写代码、摸鱼、修bug、写日报,太可爱了吧!
前端·人工智能·设计模式
_哆啦A梦6 天前
Vibe Coding 全栈专业名词清单|设计模式·基础篇(创建型+结构型核心名词)
前端·设计模式·vibecoding
阿闽ooo9 天前
中介者模式打造多人聊天室系统
c++·设计模式·中介者模式