结构型模式:①适配器模式(Adapter Pattern)
核心思想
解决接口不兼容问题:将一个类(或结构体)的接口转换成客户端期望的另一个接口,使得原本因接口不匹配而无法协同工作的类(或结构体)能够一起工作。适配器模式分为两种实现方式:
1.对象适配器:通过「组合」适配者(已存在的、接口不兼容的组件)实现,灵活性更高(优先推荐);
2.类适配器:通过「继承」适配者实现(C 语言不支持继承,仅 C++ 可实现)。
核心本质
接口转换 + 转发调用(不修改原有目标接口和适配者代码,符合开闭原则)。
C语言编写
关键要点
1.接口模拟:用「结构体 + 函数指针」分别定义目标接口(USBInterface)和适配者接口(TypeCAdapter),模拟类的方法。
2.组合优先:适配器通过结构体成员(typec_device)持有适配者实例,而非继承(C 语言无继承),符合「合成复用原则」。
3.接口转发:适配器实现目标接口的方法(usb_to_typec_charge),内部调用适配者的对应方法,完成接口转换。
4.客户端解耦:客户端仅依赖目标接口(USBInterface),无需知道适配者的存在,实现对客户端透明。
5.内存管理:通过 destroy 函数统一释放资源,避免内存泄漏。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// -------------------------- 1. 目标接口(Target):客户端期望的接口 --------------------------
// 客户端只认识 USB 接口,定义 USB 充电接口规范
typedef struct USBInterface {
// 客户端期望的方法:USB 充电
void (*usb_charge)(struct USBInterface* self);
void (*destroy)(struct USBInterface* self);
} USBInterface;
// USB 接口的销毁通用实现
void usb_destroy(USBInterface* usb) {
if (usb != NULL) {
free(usb);
}
}
// -------------------------- 2. 适配者(Adaptee):已存在的、接口不兼容的组件 --------------------------
// 现有设备的 Type-C 接口(与 USB 接口不兼容,客户端无法直接使用)
typedef struct TypeCAdapter {
// 适配者的方法:Type-C 充电
void (*typec_charge)(struct TypeCAdapter* self);
char device_name[32];
} TypeCAdapter;
// Type-C 接口的具体实现(已存在的功能)
void typec_device_charge(TypeCAdapter* self) {
printf("[%s] 使用 Type-C 接口充电中...\n", self->device_name);
}
// 创建 Type-C 适配者实例(模拟已有的设备)
TypeCAdapter* create_typec_device(const char* name) {
TypeCAdapter* device = (TypeCAdapter*)malloc(sizeof(TypeCAdapter));
strncpy(device->device_name, name, sizeof(device->device_name));
device->typec_charge = typec_device_charge;
return device;
}
void destroy_typec_device(TypeCAdapter* device) {
if (device != NULL) {
free(device);
}
}
// -------------------------- 3. 适配器(Adapter):组合适配者,实现目标接口 --------------------------
// 适配器结构体:组合 Type-C 适配者,实现 USB 目标接口
typedef struct USBToTypeCAdapter {
USBInterface base; // 继承目标接口(C语言模拟:包含目标接口结构体)
TypeCAdapter* typec_device; // 组合适配者(核心:持有适配者实例)
} USBToTypeCAdapter;
// 适配器实现 USB 接口的方法(转发调用适配者的方法)
void usb_to_typec_charge(USBInterface* self) {
// 类型转换:从目标接口指针转换为适配器指针,获取适配者实例
USBToTypeCAdapter* adapter = (USBToTypeCAdapter*)self;
// 转发调用:适配器内部调用适配者的 Type-C 充电方法
adapter->typec_device->typec_charge(adapter->typec_device);
}
// 创建适配器实例(关联目标接口和适配者)
USBInterface* create_usb_to_typec_adapter(TypeCAdapter* typec_device) {
USBToTypeCAdapter* adapter = (USBToTypeCAdapter*)malloc(sizeof(USBToTypeCAdapter));
// 绑定目标接口的方法(客户端调用的是这个方法)
adapter->base.usb_charge = usb_to_typec_charge;
adapter->base.destroy = usb_destroy;
// 关联适配者(组合关系)
adapter->typec_device = typec_device;
// 返回目标接口指针(客户端仅关注目标接口)
return (USBInterface*)adapter;
}
// -------------------------- 测试代码(客户端) --------------------------
// 客户端代码:仅依赖目标接口(USBInterface),不关心具体实现
void client_charge(USBInterface* usb_device) {
printf("客户端:连接 USB 接口,准备充电...\n");
usb_device->usb_charge(usb_device); // 调用目标接口方法
printf("充电完成!\n\n");
}
int main() {
// 1. 创建已有的 Type-C 设备(适配者)
TypeCAdapter* phone = create_typec_device("华为手机");
// 2. 创建适配器:将 Type-C 转换为 USB 接口
USBInterface* usb_adapter = create_usb_to_typec_adapter(phone);
// 3. 客户端通过适配器使用 Type-C 设备(客户端仅知道 USB 接口)
client_charge(usb_adapter);
// 4. 资源释放
usb_adapter->destroy(usb_adapter);
destroy_typec_device(phone);
return 0;
}
C++语言实现
关键要点
1.抽象基类定义接口:目标接口(USBInterface)用纯虚函数定义,强制适配器实现统一接口,保证多态。
2.对象适配器核心:
2.1继承目标接口(public USBInterface),对外暴露客户端期望的接口;
2.2组合适配者(std::shared_ptr),内部转发调用,避免多继承风险;
2.3智能指针(std::shared_ptr)自动管理内存,无需手动 delete。
3.类适配器特点:
3.1多继承(同时继承目标接口和适配者),直接复用适配者的方法;
3.2缺点:适配者不能是 final 类,且与适配者耦合度高,灵活性差,不推荐优先使用。
4.开闭原则:新增适配者(如 MicroUSBDevice)时,只需新增对应的适配器(USBToMicroUSBAdapter),无需修改客户端和原有接口。
5.多态调用:客户端通过目标接口指针 / 引用调用,实际执行适配器的实现,实现接口透明转换。
c++对象适配器(推荐)
通过「组合适配者」实现,不依赖多继承,灵活性强,符合合成复用原则。
#include <iostream>
#include <string>
#include <memory> // 智能指针,自动管理内存
// -------------------------- 1. 目标接口(Target):客户端期望的抽象基类 --------------------------
class USBInterface {
public:
virtual ~USBInterface() = default; // 虚析构:确保子类析构被调用
virtual void USBCharge() const = 0; // 纯虚函数:目标接口方法
};
// -------------------------- 2. 适配者(Adaptee):已存在的、接口不兼容的类 --------------------------
class TypeCDevice {
public:
explicit TypeCDevice(std::string name) : device_name_(std::move(name)) {}
// 适配者的方法(与目标接口不兼容)
void TypeCCharge() const {
std::cout << "[" << device_name_ << "] 使用 Type-C 接口充电中..." << std::endl;
}
private:
std::string device_name_;
};
// -------------------------- 3. 适配器(Adapter):实现目标接口 + 组合适配者 --------------------------
class USBToTypeCAdapter : public USBInterface { // 实现目标接口
public:
// 构造函数:传入适配者实例(组合关系)
explicit USBToTypeCAdapter(std::shared_ptr<TypeCDevice> typec_device)
: typec_device_(std::move(typec_device)) {}
// 实现目标接口方法:转发调用适配者的方法
void USBCharge() const override {
typec_device_->TypeCCharge(); // 适配者的核心功能
}
private:
std::shared_ptr<TypeCDevice> typec_device_; // 组合适配者(智能指针管理内存)
};
// -------------------------- 测试代码(客户端) --------------------------
// 客户端:仅依赖目标接口(USBInterface),不关心具体实现
void ClientCharge(const USBInterface& usb_device) {
std::cout << "客户端:连接 USB 接口,准备充电..." << std::endl;
usb_device.USBCharge(); // 多态调用:实际调用适配器的实现
std::cout << "充电完成!\n" << std::endl;
}
int main() {
// 1. 创建适配者实例(已有的 Type-C 设备)
std::shared_ptr<TypeCDevice> phone = std::make_shared<TypeCDevice>("苹果手机");
// 2. 创建适配器:组合适配者,对外提供 USB 接口
USBToTypeCAdapter adapter(phone);
// 3. 客户端通过适配器使用 Type-C 设备(依赖抽象,不依赖具体)
ClientCharge(adapter);
return 0;
}
c++类适配器
通过「多继承」同时继承目标接口和适配者,直接复用适配者的方法。
缺点:依赖多继承,适配者类不能是最终类(final),灵活性差。
实现代码(仅适配器部分修改)
// -------------------------- 类适配器(继承目标接口 + 适配者) --------------------------
class USBToTypeCClassAdapter : public USBInterface, public TypeCDevice { // 多继承
public:
// 构造函数:直接初始化适配者(继承关系)
explicit USBToTypeCClassAdapter(std::string name) : TypeCDevice(std::move(name)) {}
// 实现目标接口方法:直接调用父类(适配者)的方法
void USBCharge() const override {
TypeCCharge(); // 继承适配者的方法,无需组合
}
};
// 测试代码修改
int main() {
// 直接创建类适配器(无需单独创建适配者)
USBToTypeCClassAdapter class_adapter("小米平板");
ClientCharge(class_adapter); // 客户端调用方式不变
return 0;
}
设计原则
1.优先使用「组合」而非「继承」(对象适配器优于类适配器);
2.符合「开闭原则」:不修改目标接口和适配者,新增适配器扩展功能;
3.客户端依赖抽象(目标接口),不依赖具体实现(适配器 / 适配者)。
适配器模式核心总结(C vs C++)

475

被折叠的 条评论
为什么被折叠?



