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;
}
相关推荐
范纹杉想快点毕业7 小时前
实战级ZYNQ中断状态机FIFO设计
java·开发语言·驱动开发·设计模式·架构·mfc
茂桑12 小时前
DDD领域驱动设计-基础设施层
设计模式·架构
小温冲冲15 小时前
通俗且全面精讲工厂设计模式
设计模式
进击的小头15 小时前
设计模式与C语言高级特性的结合
c语言·设计模式
小温冲冲16 小时前
通俗且全面精讲单例设计模式
开发语言·javascript·设计模式
Vivienne_ChenW16 小时前
DDD领域模型在项目中的实战
java·开发语言·后端·设计模式
sg_knight17 小时前
原型模式(Prototype)
python·设计模式·开发·原型模式
短剑重铸之日17 小时前
《设计模式》第九篇:三大类型之结构型模式
java·后端·设计模式·组合模式·代理模式·结构性模式
忧郁的Mr.Li18 小时前
设计模式--单例模式
javascript·单例模式·设计模式
范纹杉想快点毕业18 小时前
状态机设计模式与嵌入式系统开发完整指南
java·开发语言·网络·数据库·mongodb·设计模式·架构