适配器模式
将类的接口转换为客户期望的另一个接口。适配器(或包装器)允许类一起工作,否则由于不兼容的接口。适配器模式的动机是,如果我们可以修改接口,我们可以重用现有的软件。
-
适配器模式依赖于对象组合。
-
客户端调用 Adapter 对象上的操作。
-
适配器调用 Adaptee 来执行操作。
-
在 STL 中,堆栈适用于向量:当堆栈执行
push()
时,底层向量执行 vector ::push_back()
。
例:
#include <iostream>
// Desired interface (Target)
class Rectangle
{
public:
virtual void draw() = 0;
};
// Legacy component (Adaptee)
class LegacyRectangle
{
public:
LegacyRectangle(int x1, int y1, int x2, int y2) {
x1_ = x1;
y1_ = y1;
x2_ = x2;
y2_ = y2;
std::cout << "LegacyRectangle(x1,y1,x2,y2)\n";
}
void oldDraw() {
std::cout << "LegacyRectangle: oldDraw(). \n";
}
private:
int x1_;
int y1_;
int x2_;
int y2_;
};
// Adapter wrapper
class RectangleAdapter: public Rectangle, private LegacyRectangle
{
public:
RectangleAdapter(int x, int y, int w, int h):
LegacyRectangle(x, y, x + w, y + h) {
std::cout << "RectangleAdapter(x,y,x+w,x+h)\n";
}
void draw() {
std::cout << "RectangleAdapter: draw().\n";
oldDraw();
}
};
int main()
{
int x = 20, y = 50, w = 300, h = 200;
Rectangle *r = new RectangleAdapter(x,y,w,h);
r->draw();
}
//Output:
//LegacyRectangle(x1,y1,x2,y2)
//RectangleAdapter(x,y,x+w,x+h)
代码摘要:
-
客户认为他正在和一个人交谈
-
目标是
Rectangle
类。这是客户端调用方法的内容。Rectangle *r = new RectangleAdapter(x,y,w,h); r->draw();
-
请注意,适配器类使用多重继承。
class RectangleAdapter: public Rectangle, private LegacyRectangle { ... }
-
适配器
RectangleAdapter
允许LegacyRectangle
通过继承 BOTH 类来响应请求(draw()
在Rectangle
上)。 -
LegacyRectangle
类没有与Rectangle
相同的方法(draw()
),但是Adapter(RectangleAdapter)
可以接受Rectangle
方法调用并转向并调用LegacyRectangle
,oldDraw()
上的方法。class RectangleAdapter: public Rectangle, private LegacyRectangle { public: RectangleAdapter(int x, int y, int w, int h): LegacyRectangle(x, y, x + w, y + h) { std::cout << "RectangleAdapter(x,y,x+w,x+h)\n"; } void draw() { std::cout << "RectangleAdapter: draw().\n"; oldDraw(); } };
适配器设计模式将一个类的接口转换为兼容但不同的接口。因此,这与代理模式类似,因为它是单组件包装器。但是适配器类和原始类的接口可能不同。
正如我们在上面的示例中看到的,此适配器模式对于为现有 API 公开不同的接口以允许其与其他代码一起使用非常有用。此外,通过使用适配器模式,我们可以采用异构接口,并对它们进行转换以提供一致的 API。
Bridge 模式具有类似于对象适配器的结构,但 Bridge 具有不同的意图:它旨在将接口与其实现分离,以便可以轻松且独立地改变它们。一个适配器是为了改变界面的的现有对象。