1 适配器模式简介
适配器模式是一种常用的设计模式,用于将一个类的接口转换成客户端所期望的另一种接口。适配器模式通常用于解决以下问题:
将现有类与新的代码进行集成。当我们需要在现有代码中使用新的类或库时,适配器模式可以帮助我们将现有代码与新的接口进行集成,从而避免大量的代码重写。
将不兼容的接口进行转换。当我们需要将一个不兼容的接口转换成客户端所期望的另一种接口时,适配器模式可以帮助我们实现这个目标。例如,当我们需要在不同的数据库之间进行数据传输时,可以使用适配器模式将不同数据库的接口进行转换。
与第三方库进行交互。当我们需要与一个第三方库进行交互时,适配器模式可以帮助我们将第三方库的接口转换成我们自己的接口,从而更容易地与其进行交互。
代码重构。当我们需要重构现有代码时,适配器模式可以帮助我们将旧的接口转换成新的接口,从而使得代码更加易于维护和扩展。
总之,适配器模式在许多情况下都是非常有用的。无论是在集成现有代码、转换不兼容的接口、与第三方库进行交互,还是进行代码重构,适配器模式都可以帮助我们更加轻松地实现我们的目标。
2 简单示例
// 基础组件 class Component { public: virtual void operation() = 0; }; // 具体组件实现 class ConcreteComponent : public Component { public: virtual void operation() { cout << "ConcreteComponent operation." << endl; } }; // 装饰器基类 class Decorator : public Component { public: Decorator(Component* component) : m_component(component) {} virtual void operation() { if (m_component) { m_component->operation(); } } protected: Component* m_component; }; // 具体装饰器实现 class ConcreteDecorator : public Decorator { public: ConcreteDecorator(Component* component) : Decorator(component) {} virtual void operation() { Decorator::operation(); addBehavior(); } private: void addBehavior() { cout << "Added behavior." << endl; } }; int main() { // 创建具体组件对象 Component* component = new ConcreteComponent(); // 使用具体装饰器包装具体组件对象 Component* decorator = new ConcreteDecorator(component); // 调用装饰器对象的 operation() 方法,动态地添加了新的行为 decorator->operation(); // 释放内存 delete decorator; delete component; return 0; }
3 项目应用代码示例
在这个示例中,我们定义了一个旧的OBD传感器接口 OldOBDSensor 和一个新
的OBD传感器接口 NewOBDSensor。旧接口只能获取整数类型的引擎转速和车速,而新接口使用一个结构体 ObdData 来获取多个OBD数据。然后,我们创建了一个适配器类 OBDAdapter,它将旧接口适配到新接口,使得旧接口的整数参数可以通过新接口的结构体参数传递。在适配器类中,我们将旧接口的整数参数转换成了新接口的结构体参数。
为了测试这个示例,我们创建了两个具体的OBD传感器实现类 OldOBDSensorImpl 和 NewOBDSensorImpl,它们分别实现了旧接口和新接口。然后,我们创建了一个旧接口的实例 oldSensor,一个适配器实例 adapter,和一个新接口的实例 newSensor。最后,我们分别使用这三个实例来测试旧接口、新接口和适配器的功能,输出了三组结果。
这个示例代码只是一个简单的示例,实际上在真实的OBD业务中可能涉及更多的数据和方法,需要更复杂的适配器和更完整的接口定义。但是,这个示例代码可以帮助你理解适配器模式的基本原理和应用场景。
#include <iostream> #include <string> // 定义旧接口 class OldOBDSensor { public: virtual int getEngineRPM() = 0; virtual int getVehicleSpeed() = 0; // ... }; // 定义新接口 struct ObdData { int engineRPM; int vehicleSpeed; // ... }; class NewOBDSensor { public: virtual ObdData getObdData() = 0; }; // 适配器类,将旧接口适配到新接口 class OBDAdapter : public NewOBDSensor { private: OldOBDSensor* oldSensor; public: OBDAdapter(OldOBDSensor* oldSensor) { this->oldSensor = oldSensor; } virtual ObdData getObdData() { ObdData data; data.engineRPM = oldSensor->getEngineRPM(); data.vehicleSpeed = oldSensor->getVehicleSpeed(); // ... return data; } }; // 旧接口的实现 class OldOBDSensorImpl : public OldOBDSensor { public: virtual int getEngineRPM() { // 实现获取引擎转速的逻辑 return 3000; } virtual int getVehicleSpeed() { // 实现获取车速的逻辑 return 60; } }; // 新接口的实现 class NewOBDSensorImpl : public NewOBDSensor { public: virtual ObdData getObdData() { // 实现获取OBD数据的逻辑 ObdData data; data.engineRPM = 4000; data.vehicleSpeed = 80; // ... return data; } }; int main() { // 使用适配器将旧接口适配到新接口 OldOBDSensorImpl* oldSensor = new OldOBDSensorImpl(); OBDAdapter* adapter = new OBDAdapter(oldSensor); NewOBDSensorImpl* newSensor = new NewOBDSensorImpl(); // 测试旧接口 std::cout << "Engine RPM using old interface: " << oldSensor->getEngineRPM() << std::endl; std::cout << "Vehicle speed using old interface: " << oldSensor->getVehicleSpeed() << std::endl; // 测试新接口 ObdData data = newSensor->getObdData(); std::cout << "Engine RPM using new interface: " << data.engineRPM << std::endl; std::cout << "Vehicle speed using new interface: " << data.vehicleSpeed << std::endl; // 测试适配器 data = adapter->getObdData(); std::cout << "Engine RPM using adapter: " << data.engineRPM << std::endl; std::cout << "Vehicle speed using adapter: " << data.vehicleSpeed << std::endl; delete oldSensor; delete adapter; delete newSensor; return 0; }
运行结果
Engine RPM using old interface: 3000 Vehicle speed using old interface: 60 Engine RPM using new interface: 4000 Vehicle speed using new interface: 80 Engine RPM using adapter: 3000 Vehicle speed using adapter: 60
首先,我们使用旧接口的实例 oldSensor 分别获取了引擎转速和车速,输出了结果 3000 和 60。然后,我们使用新接口的实例 newSensor 获取了一个包含引擎转速和车速的结构体参数 data,输出了结果 4000 和 80。最后,我们使用适配器的实例 adapter 获取了同样的结构体参数 data,输出了旧接口的引擎转速和车速,结果与旧接口的实例 oldSensor 相同,分别是 3000 和 60。这表明适配器成功地将旧接口适配到了新接口。