一、适配器模式简介
适配器模式(Adapter Pattern)是结构型设计模式之一,用于将一个类的接口转换成客户希望的另一个接口。这个模式使得原本接口不兼容的类可以在一起工作。适配器模式的核心目的是实现接口兼容性,使得系统能够使用原本不兼容的类。
GoF一书对适配器模式的介绍
二、适配器模式的关键要点
适配器(Adapter):充当客户端与目标接口之间的桥梁。它实现了客户端期望的接口,并将请求委托给被适配的对象。
目标接口(Target Interface):客户端期望使用的接口。
被适配者(Adaptee):已有的类,它的接口与客户端期望的接口不兼容。
客户端(Client):使用目标接口的代码。
三、 适配器模式的用处
1. 接口不兼容
当你有一个现有的类,其接口与客户端所期望的接口不匹配时,适配器模式可以帮助将这两个接口连接起来。这样,你可以在不修改现有代码的情况下,使得这些不兼容的接口能够协同工作。
2. 代码重用
通过适配器模式,你可以重用已有的类,而不需要对它们进行修改。适配器模式允许你将现有类包装在适配器中,从而使其能够与新的系统或接口兼容。这有助于提高代码的重用性,减少重复工作。
3. 系统集成
在集成不同系统或模块时,可能会遇到接口不兼容的问题。适配器模式可以作为桥梁,将不同系统之间的接口进行转换,使它们能够互操作。这对于系统之间的兼容性和集成非常重要。
4. 第三方库的兼容
在使用第三方库时,这些库可能与项目中的接口不兼容。通过适配器模式,可以创建一个适配器类,将第三方库的接口适配为项目所需的接口,从而使得库能够被有效地使用。
5. 引入新功能
当系统需要引入新的功能,但这些功能的接口与现有接口不兼容时,可以使用适配器模式将新功能的接口适配到现有系统中。这样,你可以无缝地将新功能集成到系统中,而无需大规模修改现有代码。
实际应用示例:
用户界面(UI)组件的适配:如果你使用了多个 UI 库或组件,这些组件可能具有不同的接口。适配器模式可以将这些组件的接口适配成统一的接口,从而简化 UI 组件的使用。
数据存储接口的适配:在数据存储系统中,不同的数据存储库(如数据库、文件系统等)可能有不同的访问接口。适配器模式可以将这些存储库的接口适配成统一的数据访问接口。
API 接口的适配:当你集成外部 API 时,这些 API 可能具有与项目中现有接口不同的设计。使用适配器模式,可以将外部 API 的接口转换为项目需要的接口。
四、适配器模式的设计方法
adapter.cpp
#include <iostream>
// 图形编辑器接口
class Shape {
public:
virtual ~Shape() = default;
virtual void draw() const = 0;
};
// 第三方库中的类
class Triangle {
public:
void renderTriangle() const {
std::cout << "Drawing a triangle" << std::endl;
}
};
// 适配器
class TriangleAdapter : public Shape {
public:
TriangleAdapter(const Triangle& triangle) : triangle_(triangle) {}
void draw() const override {
triangle_.renderTriangle(); // 调用被适配者的接口
}
private:
const Triangle& triangle_;
};
// 客户端代码
void doWorking() {
// 创建第三方库的三角形对象
Triangle triangle;
// 使用适配器将三角形适配为 Shape 接口
TriangleAdapter triangleShape(triangle);
// 使用统一的接口绘制图形
triangleShape.draw();
}
int main() {
doWorking();
return 0;
}
运行效果
五、总结
适配器模式的本质是将一个类的接口转换为客户端所希望的另外一个接口。比如手机适配器的工作电压组合各不相同,有5V/1A、5V/2A、9V/2A 、 12V/1.5A、5V/3A、9V/3A、12V/3A 和 20V/5A甚至包括无线充电也有不同的工作电压/电流组合,工作电压和电流的组合出于性能和安全为由各不相同,搞一个适配器让其根据手机的不同配置要求限制电压/电流范围,这样客户没带适配器,用别人的适配器也可以用啦,像90年代的万能充电器一样!所以适配器实际上就是为了解决接口不兼容的问题。