feat: Adapter

Implemented a demo for the Adapter.
This commit is contained in:
Yuki 2025-04-06 02:47:26 +08:00
parent 751033f2e9
commit c49faa4780
Signed by: yuki
GPG Key ID: CF40579331C06C73
2 changed files with 57 additions and 0 deletions

47
07_adapter.cpp Normal file
View File

@ -0,0 +1,47 @@
#include <iostream>
#include <memory>
using namespace std;
class Target {
string s;
public:
Target(string s) : s(s) {}
virtual ~Target() = default;
virtual void request(const string& contents) {
cout << s << " send request to server: " << contents << endl;
}
};
class Adaptee {
public:
int value;
Adaptee(int value) : value(value) {}
};
class Adapter : public Target {
shared_ptr<Adaptee> a;
public:
Adapter(shared_ptr<Adaptee> a) :
Target("User " + to_string(a->value)), a(a) {}
virtual void request(const string& contents) override {
cout << "Adapted request" << endl;
Target::request(contents);
}
};
int main() {
shared_ptr<Target> t = make_shared<Target>("User A");
t->request("Hello");
shared_ptr<Adaptee> adaptee = make_shared<Adaptee>(42);
// Obviously this is invalid.
// a->request();
// But it works with adapter.
shared_ptr<Target> adapter = make_shared<Adapter>(adaptee);
adapter->request("Bye");
}

View File

@ -39,3 +39,13 @@
有时需要在项目中创建副本,那么如何创建重复对象?很容易想到使用复制或赋值操作符,而不是普通的构造函数。但是这些方法没有多态性,如果很多子类需要复制就会有点麻烦。
解决方案也很简单,父类提供一种 `clone` 方法。这样客户端只需要调用 `clone` 方法,不需要知道这个类具体是什么。这种方法常配合对象注册表使用,通过维护一个原型缓存容器(如`map<string, Prototype*>`),根据名字/类型复制对象。
## 适配器模式Adapter
在开发过程中,可能会遇到接口不兼容的情况。例如,类 `A` 有一个向服务器发送请求的接口,而类 `B` 也需要实现类似的功能,但它并不继承自 `A`,因此无法通过多态方式调用 `A` 的接口。
一种解决方法是让 `B` 继承 `A`,这是一个很推荐的做法,但是这样做并不总是可行的,特别是当 `B` 是由他人设计或无法修改时。此时,可以设计一个适配器类。
适配器类可以继承自 `A`,并将 `B` 作为构造参数。在构造过程中,适配器将 `B` 的接口转换为符合 `A` 的接口形式。这样,通过适配器,`B` 就可以像 `A` 一样调用接口,达到接口兼容的效果。考虑到适配性,比如希望这个适配器类还能适配其他的 `C``D` 等,可以让适配器类接受一个更普遍的共性作为构造参数。
需要注意的是,这种做法显然会使得代码复杂很多,条件允许的话,还是直接修改 `B` 类较好。