C++设计模式之适配器

动机

在软件系统中,由于应用环境的变化,常常需要将"一些现存的对象"放在新的环境中应用,但是新环境要求的接口是这些现存对象所不满足的。

如何应对这种"迁移的变化"?如何既能利用现有对象的良好实现,同时又能满足新的应用环境所要求的接口?

代码示例

cpp 复制代码
//目标接口(新接口)
class ITarget{
public:
    virtual void process()=0;
};

//遗留接口(老接口)
class IAdaptee{
public:
    virtual void foo(int data)=0;
    virtual int bar()=0;
};

//遗留类型
class OldClass: public IAdaptee{
    //....
};

//对象适配器
class Adapter: public ITarget{ //继承
protected:
    IAdaptee* pAdaptee;//组合
    
public:
    
    Adapter(IAdaptee* pAdaptee){
        this->pAdaptee=pAdaptee;
    }
    
    virtual void process(){
        int data=pAdaptee->bar();
        pAdaptee->foo(data);        
    }     
};


//类适配器
class Adapter: public ITarget,
               protected OldClass{ //多继承
                             
}


int main(){
    IAdaptee* pAdaptee=new OldClass();
      
    ITarget* pTarget=new Adapter(pAdaptee);
    pTarget->process();    
}


class stack{
    deque container;
    
};

class queue{
    deque container;
    
};

适配器模式定义

将一个类的接口转换成客户希望的另外一个接口。 Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

要点总结

Adapter模式主要应用于"希望复用一些现存的类,但是接口又与复用环境要求不一致的情况",在遗留代码复用、类库迁移等方面非常有用。

GoF23定义了两种Adapter模式的实现结构:对象适配器和类适配器。但类适配器采用多继承"的实现方式,一般不推荐使用。对象适配器采用"对象组合"的方式,更符合松耦合精神。

Adapter模式可以实现的非常灵活,不必拘泥于Gof23中定义的两种结构。例如,完全可以将Adapter模式中的"现存对象"作为新的接口方法参数,来达到适配的目的。

chatGPT给出的adapter例子

下面是一个简单的C++ Adapter 模式的例子,假设有一个旧的类 OldClass,其接口不符合新的需求,然后通过适配器 Adapter 将其适配为符合新需求的接口:

cpp 复制代码
#include <iostream>

// 旧的类,接口不符合新需求
class OldClass {
public:
    void legacyMethod() {
        std::cout << "Legacy method of OldClass" << std::endl;
    }
};

// 新的接口,符合新需求
class NewInterface {
public:
    virtual void newMethod() = 0;
    virtual ~NewInterface() {}
};

// 适配器,将OldClass适配为NewInterface
class Adapter : public NewInterface {
private:
    OldClass oldInstance;

public:
    void newMethod() override {
        // 在这里调用OldClass的方法,以适应新的接口
        oldInstance.legacyMethod();
    }
};

// 客户端代码,使用新的接口
void clientCode(NewInterface* newObject) {
    newObject->newMethod();
}

int main() {
    // 使用适配器将OldClass适配为NewInterface
    Adapter adapter;

    // 客户端代码使用新的接口
    clientCode(&adapter);

    return 0;
}

在这个例子中,OldClass 是一个旧的类,具有 legacyMethod 方法,但其接口不符合 NewInterface 的新需求。通过创建一个适配器类 Adapter,它继承了 NewInterface 并持有一个 OldClass 的实例,将 legacyMethod 适配为 newMethod。最后,在客户端代码中,我们可以使用 NewInterface 的接口,而实际上调用了 OldClass 的方法。这就是 Adapter 模式的作用。

相关推荐
小小龙学IT3 小时前
DuckDB 深度实战:用 C++ 在进程内跑一个「分析型数据库」
数据库·c++
知无不研4 小时前
lambda表达式的使用(3)
开发语言·c++·lambda
cfm_29145 小时前
SpringAI + Ollama 本地大模型
java·开发语言·人工智能·语言模型
C++ 老炮儿的技术栈6 小时前
基于Qt实现轻量化本地音乐播放器
开发语言·c++·qt·c·播放器·音乐
qq_448011166 小时前
C语言中的柔性数组
c语言·开发语言·柔性数组
小白学大数据6 小时前
长周期爬虫的数据一致性:断点续爬 + 事务回滚保障采集质量
开发语言·爬虫·测试工具
zlinear数据采集卡7 小时前
D223上位机C#开发实战:从帧解析到波形显示的完整实现
开发语言·arm开发·嵌入式硬件·fpga开发·开源·c#
Poo_Chai7 小时前
QT emit信号后完整处理流程,包括槽函数响应流程
java·开发语言·数据库
瑞码空间7 小时前
Java 图形界面(GUI)完整知识点手册
java·开发语言·图形界面·swing
小努蛋8 小时前
linux编译openresty异常问题,lua_cjson.c:706:5: 错误: ‘for‘ 循环初始化声明只在 C99 或 C++ 模式下允许
开发语言·lua·openresty