[设计模式]结构模式-适配模式(C++描述)

C++结构型模式-组合模式 C++实现组合模式 阅读详情

[设计模式]结构模式-适配模式(C++描述)

second60 20180429

1. 什么是适配模式

在现有接口中,不修改原有接口的情况下,增加适配器,支持客户的需求。

适配器分为:类适配器模式和对象适配器模式。

现实生活中最简单的例子:手机能电器,我们家用电压为220V(Adaptee),但我们的手机只需12V的电压(Target)来充电。所以中间需要一个电压适配器(Adapter)来转换电压。

概念:

接口继承:通过继承子类获得了父类的接口(子类实现父类接口)

实现继承:通过继承子类获得父类的实现(子类调用父类接口)

在C++中

public继承:即是接口继承,也是实现继承(能重载父类的接口,又获得父类的接口实现)。

private继承:父类中的接口都变为private,只能是实现继承。

纯抽象基类:可以模似接口继承。

2. 适配器模式结构图

 

类适配模式

 

对象适配模式

区别:

类适配模式的Adapter采用继承的方式实现Adaptee的接口。

对象模式的Adapter中采用组合的方式实现Adaptee接口。

分析:

1. Target为面向用户的接口

2. Adaptee为原有功能接口

3. Adapter为适配器,在原有的接口上适配新功能

3 代码实现

3.1对象适配模式

#include <iostream>
using namespace std;

// 目标接口
class Target
{
public:
    virtual ~Target(){}
    virtual void Request()
    {
        cout << "Target::Request" << endl;
    }
}; 

// 原有接口
class Adaptee
{
public:
    Adaptee(){}
    ~Adaptee(){}

    void SpecificRequest()
    {
        cout << "Adaptee::SpecificRequest" << endl;
    }
};

// 适配器
class Adapter: public Target
{
public:
    Adapter(Adaptee* adaptee):_adaptee(adaptee){}
    ~Adapter() override {}

    void Request()
    {
        cout << "do before" << endl;
        _adaptee->SpecificRequest();
        cout << "do after" << endl;
    }

private:
    Adaptee* _adaptee;
};

int main()
{
    Adaptee *adaptee = new Adaptee();
    Target* target = new Adapter(adaptee);
    target->Request();

    delete target;
    delete adaptee;

    return 0;
}

3.2 类适配模式

#include <iostream>
using namespace std;

// 目标接口
class Target
{
public:
    virtual ~Target(){}
    virtual void Request()
    {
        cout << "Target::Request" << endl;
    }
};

// 原有接口
class Adaptee
{
public:
    Adaptee(){}
    virtual ~Adaptee(){}
    void SpecificRequest()
    {
        cout << "Adaptee::SpecificRequest" << endl;
    }
};

//适配器, public 为接口继承和实现继承,private为实现继承
class Adapter: public Target, private Adaptee
{
public:
    Adapter(){}
    ~Adapter() override {}

    void Request()
    {
        cout << "do before" << endl;
        Adaptee::SpecificRequest();
        cout << "do after" << endl;
    }
};

int main()
{
    Target *target = new Adapter();
    target->Request();

    delete target;

    return 0;
}

4 适配器的使用场景

适配器模式使用非常广泛,非常常用。

在系统开发中,经常遇上这样的问题:在已经开发好了一套接口,或使用第三方接口,但是接口对于现在需求并不适合,需要通过一定的修改在支持,而不想改变原有的逻辑。此时,适配器就派上了用场。

使用条件:

1. 原有接口不适用客户需求

2. 客户无须只知内部实现,只知道接口。

例1:用户需求,某系统保存玩家信息。用户并不关心你使用什么数据库,只需保存玩家信息即可。设计的时候,一开始采用MYSQL 数据库,但后来又采用ORACLE数据库。这就非常适合用适配器,用Target写一套标准API给用户调用即可,对于接口基本实现由Adapter配置实现。

#include <iostream>
#include <memory>  // for smart pointers
using namespace std;

// 1. 目标接口(纯虚函数定义规范)
class DBTarget {
public:
    virtual ~DBTarget() {}
    
    // 纯虚函数:强制子类实现
    virtual int insert() = 0;
    virtual int remove() = 0;   // ✅ 避免使用关键字
    virtual int update() = 0;
    virtual int query() = 0;    // ✅ 避免与标准库 select 冲突
};

// 2. 数据库适配器抽象基类
class DBAdaptee {
public:
    virtual ~DBAdaptee() {}
    
    virtual int insert() = 0;
    virtual int remove() = 0;
    virtual int update() = 0;
    virtual int query() = 0;
};

// 3. 具体数据库实现
class MysqlAdaptee : public DBAdaptee {
public:
    int insert() override { 
        cout << "MySQL: 插入数据" << endl; 
        return 0;
    }
    int remove() override { 
        cout << "MySQL: 删除数据" << endl; 
        return 0;
    }
    int update() override { 
        cout << "MySQL: 更新数据" << endl; 
        return 0;
    }
    int query() override { 
        cout << "MySQL: 查询数据" << endl; 
        return 0;
    }
};

class OracleAdaptee : public DBAdaptee {
public:
    int insert() override { 
        cout << "Oracle: 插入数据" << endl; 
        return 0;
    }
    int remove() override { 
        cout << "Oracle: 删除数据" << endl; 
        return 0;
    }
    int update() override { 
        cout << "Oracle: 更新数据" << endl; 
        return 0;
    }
    int query() override { 
        cout << "Oracle: 查询数据" << endl; 
        return 0;
    }
};

class Db2Adaptee : public DBAdaptee {
public:
    int insert() override { 
        cout << "DB2: 插入数据" << endl; 
        return 0;
    }
    int remove() override { 
        cout << "DB2: 删除数据" << endl; 
        return 0;
    }
    int update() override { 
        cout << "DB2: 更新数据" << endl; 
        return 0;
    }
    int query() override { 
        cout << "DB2: 查询数据" << endl; 
        return 0;
    }
};

// 4. 适配器类(对象适配器)
class Adaptor : public DBTarget {
public:
    // 使用智能指针明确所有权
    explicit Adaptor(std::shared_ptr<DBAdaptee> adaptee) 
        : _adaptee(adaptee) {}
    
    int insert() override { 
        return _adaptee->insert(); 
    }
    int remove() override { 
        return _adaptee->remove(); 
    }
    int update() override { 
        return _adaptee->update(); 
    }
    int query() override { 
        return _adaptee->query(); 
    }

private:
    std::shared_ptr<DBAdaptee> _adaptee;
};

// 5. 工厂类(创建具体数据库对象)
class DBAdapteeFactory {
public:
    enum DBType {
        MYSQL = 0,
        ORACLE,
        DB2
    };
    
    static std::shared_ptr<DBAdaptee> create(DBType type) {
        switch (type) {
            case MYSQL:  return std::make_shared<MysqlAdaptee>();
            case ORACLE: return std::make_shared<OracleAdaptee>();
            case DB2:    return std::make_shared<Db2Adaptee>();
            default:     return nullptr;
        }
    }
};

// 6. 配置类(模拟)
class Config {
public:
    static DBAdapteeFactory::DBType db_type;
};
DBAdapteeFactory::DBType Config::db_type = DBAdapteeFactory::MYSQL;

// 7. 主函数
int main() {
    // 配置读取(示例)
    Config::db_type = DBAdapteeFactory::MYSQL;
    
    // 工厂模式生成 DBAdaptee
    auto dbAdaptee = DBAdapteeFactory::create(Config::db_type);
    if (!dbAdaptee) {
        cerr << "创建数据库适配器失败" << endl;
        return -1;
    }
    
    // 使用适配器
    auto dbTarget = std::make_shared<Adaptor>(dbAdaptee);
    
    dbTarget->query();   // MySQL: 查询数据
    dbTarget->update();  // MySQL: 更新数据
    dbTarget->insert();  // MySQL: 插入数据
    dbTarget->remove();  // MySQL: 删除数据
    
    // 智能指针自动释放内存,无需手动 delete
    return 0;
}

分析:

1. 上面DB适配器,无需修改任何代码,只需修改配置,即可支持不同数据库

2. 用户无须关心内部接口的实现

3. 如果需要新增数据库(MongoDB),只需添加MongoDBAdaptee,和工厂支持即可。

其实,上面的DB例子就是通用的DB适配器,对用户做到DB无关性。

5 总结

上面的例子,简单的讲了适配器的例子,想必都清楚适配器的优点了。我就不多说了。设计模式对于面向对象设计是博大精深。

  

【C++设计模式】Adapter 适配器模式详解 适配器模式概述 、适配器模式结构与实现 、适配器模式的应用实例:篮球翻译适配器 、适配器模式的适用场景 、适配器模式的优缺点 阅读详情

相关推荐

设计模式之适配器模式C++实现

用c++方法实现AdapterPattern模式

【C++】适配器模式

C++中的适配器是一种设计模式用于将一个类或对象的接口转换为另一个接口,以便不同的类或对象可以相互协作。适配器模式可以分为类适配器和对象适配器两种形式。类适配器通过继承源类并实现目标接口来实现适配。在类适配器中,适配器类同时继承自源类和目标接口,并重新实现目标接口的方法,以将源类的方法转换为目标接口的方法。对象适配器则通过在适配器类中包装一个源对象来实现适配。在对象适配器中,适配器类持有一个源对象的引用,并实现目标接口的方法,在方法内部调用源对象的相应方法来完成适配。

weixin_73914025的博客 1788

设计模式 - 适配器模式(C++实例)

适配器模式 设计模式 Adapter 还请各位大S指教

【第九节】C++设计模式(结构型模式)-Composite(组合)模式

组合模式通过统一接口简化了树形结构的操作,尤其适用于需要递归处理对象的场景。其核心在于以一致的方式对待单个对象和组合对象,从而降低代码复杂度并提高扩展性。

攻城狮7号的博客 930

Linux安装Oracle sqlplus客户端工具

Linux安装Oracle sqlplus客户端工具

优快云_Nan_Jiang_Li的博客 2776

【招聘测评题】中的(行测)图形推理题基本逻辑总结(附例题)

参加招聘的时候,一般提交完简历就需要做测评试卷,测评里面除了性格分析的题,一般会有几十道类似公务员行测的素质测评题,让人很是挠头,据说题库多取自北森。刷题用处不大,这里总结一下图形推理题中常考的几个基本逻辑。

Yujian2563的博客 7万+

C++ 设计模式——适配者模式

适配者模式(Adapter Pattern)是一种结构型设计模式,主要用于解决接口不兼容的问题。其核心思想是通过创建一个适配器类,将一个类的接口转换成客户端所期待的另一种接口。

慢慢记录,慢慢更新。 1516

Android CPU调度优化完整分析 - 小白入门到精通

本文全面解析Android CPU调度优化技术,从硬件架构到内核实现。首先介绍ARM big.LITTLE架构的硬件拓扑和性能层级,包括大核、小核和DynamIQ技术。然后深入讲解CPU性能状态管理(P-states和C-states)和硬件计数器支持。内核层部分详细分析调度器架构,包括调度类层次结构和核心调度实体实现,重点剖析CFS调度器的虚拟运行时间计算、红黑树操作和PELT负载跟踪算法。最后探讨负载均衡触发条件和实现机制。全文循序渐进,为开发者提供完整的Android CPU调度优化知识体系。

xhxh510573522125的博客 152

c++设计模式之概括--结构型模式

c++设计模式之概括–结构型模式 结构类模式都是原来的类已经定型, 现在需要在原基础上进行一些优化,功能控制,功能扩充等, 我们应该怎么做的问题. 那就是,保留一个原对象的指针, 当对我们的包装类调用的时候,我们 要恰当的调用保留的对象的函数. 包装,当然是有目的的. 结构型模式: 适配器模式:将一个物件的界面’转接’成当事人预期的样子。 目的,协调两类工作 桥接模式:将一个抽象与实现解耦,以...

hjjdebug的专栏 420

基于STM32F103的智能门禁门锁门卫系统设计

本文设计了一种基于STM32F103单片机的智能门禁系统,集成了密码、射频IC卡和指纹识别三种验证方式。系统采用模块化设计,包含MFRC522射频模块、AS608指纹模块、矩阵键盘、OLED显示和舵机控制等硬件,实现了身份验证、密码修改、IC卡/指纹管理以及安全防护功能。测试结果表明系统响应迅速(密码验证250ms、指纹验证600ms)、功耗低(待机50mA),且具备掉电密码保存功能。该系统操作简便、功能完善,适用于家庭和办公场所,具有较高实用价值。未来可扩展远程控制、人脸识别等功能以进一步提升智能化水平。

3254968421的博客 317

AI幻觉缓解的成本效益分析:投入产出比优化

在当今AI技术飞速发展的时代,AI幻觉成为了一个不容忽视的问题。AI幻觉就像是AI在“做梦”,会给出一些不符合实际或者错误的答案。我们这篇文章的目的就是要分析缓解AI幻觉所需要投入的成本和能够获得的效益,看看怎么能让投入和产出的比例达到最优。范围涵盖了常见的AI应用场景,比如智能客服、自动驾驶等领域。接下来,我们会先介绍一些和AI幻觉、成本效益分析相关的术语。然后用一个有趣的故事引出核心概念,解释什么是AI幻觉、成本效益分析等,以及它们之间的关系。

AI 原生应用开发的博客 935

[设计模式]结构模式-桥接模式(C++描述)

[设计模式]结构模式-桥接模式(C++描述)second60 201804281. 什么是结构模式设计模式中有三种模式,分别是:创建型模式,结构型模式,行为模式。 1.1三种模式的区别创建型模式:创建对象的模式,抽象了实例化的过程。结构型模式:解决怎么组装现有的类,设计他们的交互,从而达到实现一定的功能。行为模式:描述了对象和类的模式,以及它们间的通信模式。 1.2 结构模式从上面的概念,可以知道...

second60的博客 432

红火蚁巢穴AI智能识别,提供方案与思路!

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 1041

C++设计模式概念与设计模式描述语言(UML)

参考文献:

灰太狼的小秘密 3858

高速PCB设计中的一些常用规则

目前,高速PCB产品设计中,高速接口的应用日益普及,对于复杂的设计而言,高速走线就如同“蜘蛛网”一样密布在PCB各处,因此,在进行PCB检查及评审时,必要的高速PCB设计经验法则及规则是工程师开展工作必不可少的知识储备。

一只豌豆象的博客 3414

ANSYS——“There is at least 1 small equation solver pivot term”问题的解决办法

ANSYS——“There is at least 1 small equation solver pivot term”问题的解决办法

python_AI_fans的博客 1万+

C++各类设计模式及实现详解

总结了网上一些设计模式资料。     软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性:封装、继承、多态,真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积累。最近看设计模式的书,对于每个模式,用C++写了个小例子,加深一下理解。主要参考《大话设计模式》和《设计模式:可复用面向对象软件的基础》两本书。

Seven 4万+

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

细数C++的各种设计模式

访问者模式是一种行为型设计模式,它定义了在不改变对象结构的情况下对集合中的元素进行操作的方式。代理模式是一种结构模式,通过在对象之间提供一个代理对象来控制对象的访问。命令模式是一种行为型模式,将请求封装成对象,使得可以使用不同的请求、日志、事务和支持撤销操作的操作来对请求进行参数化。模板方法模式是一种行为型设计模式,它定义了一个算法的骨架,允许子类重写特定方法的实现,而不改变算法的结构。观察者模式是一种行为型模式,用于在对象之间定义一对多的依赖关系,以便当对象的状态发生改变时通知其他对象。

2301_78032663的博客 2571

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

C++设计模式项目教程

C++设计模式项目教程 1. 项目目录结构及介绍 design-patterns/ ├── BehaviroalPatterns/ │ ├── ChainOfResponsibility/ │ ├── Command/ │ ├── Interpreter/ │ ├── Iterator/ │ ├── Mediator/ │ ├── Memento/ │ ├── Obse...

gitblog_00034的博客 494

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

23种设计模式-7种结构模式

把类或对象结合在一起形成一个更大的结构。 装饰器模式:动态的给对象添加新的功能。 代理模式:为其它对象提供一个代理以便控制这个对象的访问。 桥接模式:将抽象部分和它的实现部分分离,使它们都可以独立的变化。 适配器模式:将一个类的方法接口转换成客户希望的另一个接口。 组合模式:将对象组合成树形结构以表示“部分-整体”的层次结构。 外观模式:对外提供一个统一的方法,来访问子系统中的一群接口。 享元模式:通过共享技术来有效的支持大量细粒度的对象。

JesonYang的IT之路 697

C++ · 设计模式 (接口隔离=Adapter<适配器>)

将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的类可以一起工作。适配器模式是集成不兼容接口的强大工具,特别适合C++这种需要与多种语言和系统交互的环境。

qq_35223555的博客 787

23种设计模式C++实例之代理模式

代理的目的是一般是为了防止直接访问某一个类,提供一种类似授权的机制。 最典型的类中set和get方法实际上就是一种代理。 #include using namespace std; /* * 代理模式:为其他对象提供一种代理,并以控制对这个对象的访问 * a类中b类,a类和b类中都实现协议类protocol * */ class Shop{ public: virt

寒风的技术博客 1549

c++ 单例模式_你应该了解的 5 种 TypeScript 设计模式

本文最初发布于 Medium 网站,经原作者授权由 InfoQ 中文站翻译并分享。设计模式是解决问题的良好模板,开发人员可以在自己的项目应用这些模式处理需求。现实中应付各种需求的模式数不胜数,一篇文章无法尽述。不过它们可以大致分为三个类别:结构模式,负责处理不同组件(或类)之间的关系,并形成新结构以提供新功能。结构模式的例子有组合(Composite)、适配器(Adapter)和装饰器(Decor...

weixin_39844515的博客 127

23种设计模式C++实例之适配器模式

适配器模式目的为了向客户提供他们所需要的接口,在适配器内部再调用我们自己已经实现的接口。 #include using namespace std; /* * 电压适配器 * 将220v适配到18v * */ class Cur18v { public: virtual void useCur18v() = 0; }; class Cur220

寒风的技术博客 1424

【设计模式】23种设计模式详解

前言 23种设计模式

码农印象 478

C++ QT设计模式:库与设计模式

库(lib)是一个文件,它包含一个或者多个编译后文件(称为目标文件),并对其进行了索引,以便连接器能更容易地找到符号以及它们的定义。

buhuiCyvyan的博客 378
上一篇: [设计模式]结构模式-桥接模式(C++描述)
下一篇: [设计模式]结构模式-装饰器模式(C++描述)
second60
博客等级 码龄9年 155粉丝 88原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值