设计模式之适配器模式

通俗地说,适配器模式(Adapter Pattern) 就像是一个"插头转换器"。

当你去国外旅游,带了一个三孔插头的电脑,但酒店只有双孔插座时,你不需要拆了电脑电源线,也不需要拆了酒店的墙,你只需要买一个转换器。


1. 场景需求

我们有一个旧的支付系统 ,它只接受 string 类型的账号。现在引入了一个新的支付系统 ,它要求传入 int 类型的 ID。

方案 A:不用设计模式(硬改代码)

如果不使用适配器,我们通常会直接修改客户端逻辑,或者强行去改旧系统的接口。

复制代码
#include <iostream>
#include <string>

// 旧系统:只支持字符串 ID
class OldPaySystem {
public:
    void payByString(std::string account) {
        std::cout << "使用旧系统支付,账号: " << account << std::endl;
    }
};

// 客户端代码
int main() {
    OldPaySystem* oldSys = new OldPaySystem();
    int myID = 12345;

    // 痛点:客户端必须自己手动转换,代码变得臃肿且重复
    std::string convertedID = std::to_string(myID); 
    oldSys->payByString(convertedID);

    delete oldSys;
    return 0;
}

方案 B:使用适配器模式

我们创建一个"转换器"类,让它继承新接口,并在内部调用旧系统。

复制代码
#include <iostream>
#include <string>

// 目标接口:新系统希望看到的接口
class NewPayInterface {
public:
    virtual void pay(int id) = 0;
    virtual ~NewPayInterface() {}
};

// 旧系统(Adaptee):代码已经存在,不想去动它
class OldPaySystem {
public:
    void payByString(std::string account) {
        std::cout << "通过适配器转换,最终使用旧系统支付: " << account << std::endl;
    }
};

// 适配器类(Adapter):把 int 转换成 string,再塞给旧系统
class PayAdapter : public NewPayInterface {
private:
    OldPaySystem* oldSys; // 持有旧系统的引用
public:
    PayAdapter(OldPaySystem* sys) : oldSys(sys) {}
    
    void pay(int id) override {
        // 在这里进行"强转"或逻辑适配
        std::string strID = std::to_string(id);
        oldSys->payByString(strID);
    }
};

// 客户端代码
int main() {
    OldPaySystem* oldSys = new OldPaySystem();
    NewPayInterface* adapter = new PayAdapter(oldSys);

    // 客户端现在只需要关心新接口,传入 int 即可
    adapter->pay(88888);

    delete adapter;
    delete oldSys;
    return 0;
}

2. 优缺点对比

特性 不用模式(硬编码) 使用适配器模式
代码耦合度 客户端直接依赖旧系统的具体实现,改动一处,处处要改。 客户端只依赖目标接口,与旧系统解耦。
代码整洁度 业务代码中充斥着大量的类型转换(如 to_string)。 转换逻辑被封装在适配器里,主流程很干净。
可维护性 差。如果要换一个支付供应商,得翻遍所有业务代码。 好。只需要换一个适配器,或者修改适配器内部逻辑。
开销 运行效率极高(无额外对象调用)。 极小的性能损失(多了一层函数调用)。

3. 增加需求时的改动点对比

假设新需求: 现在需要增加一个日志记录功能,每次支付前都要记录一下。

  • 不用模式: 你得在每一个调用 payByString 的地方去手动加一句 cout << "Log..."。如果你有 100 个地方在支付,你就得改 100 处。

  • 使用适配器: 你只需要改动 PayAdapter::pay 这一个函数 。在调用 oldSys->payByString 之前加一行日志代码,全系统的支付功能瞬间都带上了日志。


总结

适配器模式的核心价值在于: 保护现有的稳定代码不被修改,同时让互不兼容的接口能够协同工作。它遵循了设计模式中的"开闭原则"(对扩展开放,对修改关闭)。

相关推荐
sarasuki7 小时前
Agent 的记忆有几种?你的名字是?
人工智能·设计模式·agent
geovindu12 小时前
rust: Flyweight Pattern
开发语言·后端·设计模式·rust·享元模式·结构型模式
沫璃染墨1 天前
《Linux工程实践篇(一):认识设计模式——从日志系统看策略模式》
linux·c++·安全·设计模式·策略模式
十六宿舍1 天前
【软件设计模式-第一课:基础知识了解】
设计模式·架构·面向对象·软件架构
geovindu1 天前
rust: Facade Pattern
开发语言·后端·设计模式·rust·外观模式
怕浪猫1 天前
面试官让我手写一个 Tool Use,我用了 3 种方案
设计模式·面试·程序员
geovindu2 天前
rust: Abstract Factory pattern
开发语言·后端·设计模式·rust·抽象工厂模式
yuehuaxin012 天前
LP20R100FN 同步整流|3C 认证适配器 CCM 工况倒灌、温升超标样机避坑解析
嵌入式硬件·智能家居·适配器模式·智能硬件
yuehuaxin012 天前
LP3710S 原边 PSR|3C 认证适配器 Peak‑Load 瞬时冲击、EMI 传导骚扰样机避坑解析
嵌入式硬件·适配器模式·智能硬件
Carl_奕然2 天前
【智能体】Loop 的四种设计模式之:Event-Driven Loop(2026 最新版)
人工智能·驱动开发·python·设计模式