C++结构型设计模式之适配器模式概述
适配器模式的意图和动机
意图:适配器模式(Adapter Pattern)是一种结构型设计模式,其意图是将一个类的接口转换成客户端所期望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的类可以协同工作。
动机:在软件开发过程中,我们经常会遇到需要使用一些已有的类库或组件,但这些类库或组件的接口与当前系统的接口不兼容。为了复用这些已有的组件,同时又不修改已有代码,适配器模式提供了一种灵活的解决方案。
适配器模式适用于解决的问题
- 接口不兼容:当需要使用一个已有类的功能,但其接口与客户端代码的接口不兼容时。
- 复用已有组件:在不修改已有类的情况下,复用其功能,并使其适应新的接口。
- 多接口适配:在需要将多个不同的接口适配成一个统一接口的场景中。
适配器模式的适用场合
- 已有类的接口与客户端不兼容:当需要使用一个已有类的功能,但其接口与客户端代码的接口不兼容时。
- 第三方库或组件的兼容性问题:当引入第三方库或组件时,其接口与现有系统的接口不兼容。
- 多接口适配:当需要将多个不同的接口适配成一个统一接口的场景中。
适配器模式的结构和参与角色
适配器模式涉及以下角色:
- Target(目标接口):客户端期望的接口。
- Adapter(适配器):实现了目标接口,同时持有对Adaptee的引用,并将客户端的请求适配到Adaptee的操作上。
- Adaptee(被适配者):已有的类或对象,其接口与目标接口不兼容。
- Client(客户端):与目标接口交互的对象。
UML 类图
以下是适配器模式的 UML 类图:
+-------------------+ +-------------------+
| Target | | Adapter |
|-------------------| |-------------------|
| + request() |<----------|>+ request() |
+-------------------+ |-------------------|
| - adaptee: Adaptee|
|-------------------|
| + request() |
|-------------------|
| + doSomething() |
+-------------------+
|
|
V
+-------------------+
| Adaptee |
|-------------------|
| + doSomething() |
+-------------------+
类图说明
- Target:定义了客户端所期望的接口。
- Adapter:实现了目标接口
Target
,并包含一个Adaptee
对象的引用。Adapter
将Target
接口的request()
方法映射到Adaptee
的doSomething()
方法。 - Adaptee:已有的类或对象,其接口与目标接口不兼容。
Adaptee
有一个doSomething()
方法,客户端无法直接使用该方法。 - Client:与
Target
接口交互的对象,通过Adapter
间接调用Adaptee
的功能。
示例代码
以下是一个简单的C++示例代码,展示了适配器模式的实现:
#include <iostream>
// Target 接口
class Target {
public:
virtual void request() const = 0;
};
// Adaptee 类
class Adaptee {
public:
void doSomething() const {
std::cout << "Adaptee: Doing something." << std::endl;
}
};
// Adapter 类
class Adapter : public Target {
private:
Adaptee* adaptee;
public:
Adapter(Adaptee* adaptee) : adaptee(adaptee) {}
void request() const override {
adaptee->doSomething();
}
};
// 客户端代码
int main() {
Adaptee* adaptee = new Adaptee();
Target* adapter = new Adapter(adaptee);
adapter->request(); // 调用适配器的方法
delete adaptee;
delete adapter;
return 0;
}
总结
适配器模式通过引入一个适配器类,将不兼容的接口转换成客户端所期望的接口,从而解决了接口不兼容的问题。它适用于需要复用已有组件但接口不兼容的场景,通过适配器模式,可以避免修改已有代码,提高系统的灵活性和可扩展性。