适配器(
Adapter
)是一种设计模式,它允许不兼容接口的类能够一起工作。适配器模式通过创建一个中间层来实现两个不兼容接口之间的通信,而无需修改现有的代码。
我们日常使用的手机,平板,笔记本的充电器就是类似适配器的作用。一般的家庭用电都是 220V
,而一般笔记本电脑的充电电压为 20V
,笔记本电脑充电器的作用就是 将家庭用电转换成笔记本能够接受的电压进行充电。
在软件开发中同样有着类似的情况,就是已有的接口,与我们需要的接口不匹配,这时我们就可以增加一个适配器将二者匹配起来。
类的接口不兼容:当你想要使用一个已存在的类,但是其接口与你的需求不匹配时,可以使用适配器模式来适配这个类的接口。
类的重新使用:当你想要重新使用一些已存在的类,但是这些类与新的环境要求不匹配时,适配器模式可以让你在新环境中使用这些类。
接口的转换:当你有一个类,它的接口与你所需的接口不同,但是你又不能修改这个类时,可以使用适配器模式将这个类的接口转换成你所需的接口。
已经有一个类 Rectangle
表示一个矩形:
rectangle(double x1,double y1,double x2,double y2)
,用对角线上的两个顶点唯一的表示一个矩形;rectangle_draw()
,打印出该矩阵的信息;现在需要的是 (double x , double y , double w , double h)
其中的一个顶点,加 宽 和 高,表示一个矩形。
我们需要打印出这个矩形的信息。
对于这个例子我们就可以使用 适配器模式。将 (double x , double y , double w , double h)
转换成 (double x1,double y1,double x2,double y2)
并打印矩形的信息。
class Rectangle {
public:
Rectangle(double x1,double y1,double x2,double y2):_x1(x1),_y1(y1),_x2(x2),_y2(y2){}
void rectangle_draw() {
cout << "Retangle::retangle_draw : " << _x1 << " " << _y1 << " " << _x2 << " " << _y2 << '\n';
}
private:
double _x1, _y1;
double _x2, _y2;
};
class RectangleInterface {
public:
virtual void draw() = 0;
};
class RectangleAdapter :public Rectangle,public RectangleInterface {
public:
RectangleAdapter(double x,double y,double h,double w) : Rectangle(x,y,x + w,y + h){}
void draw() {
cout << "RectangleAdapter::drawdraw()" << '\n';
rectangle_draw();
}
};
我们发现 RectangleAdapter
同时继承了 Rectangle
和 RectangleInterface
,即多继承。
对于 (double x , double y , double w , double h)
这样的接口,我们之间调用 RectangleAdapter (double x,double y,double h,double w)
,它实际调用的是 Rectangle(x,y,x + w,y + h)
。
对于 RectangleAdapter::draw()
,它实际调用的也是 Rectangle::rectangle_draw()
。
这样就实现了将 (double x , double y , double w , double h)
跟 (double x1,double y1,double x2,double y2)
的转换。
不过继承属于是强耦合,我们使用的比较多的是方式二,也就是组合的方式。
class Rectangle {
public:
Rectangle(){}
Rectangle(double x1,double y1,double x2,double y2):_x1(x1),_y1(y1),_x2(x2),_y2(y2){}
void reactangle_draw() {
cout << "Retangle::retangle_draw : " << _x1 << " " << _y1 << " " << _x2 << " " << _y2 << '\n';
}
private:
double _x1, _y1;
double _x2, _y2;
};
class RectangleInterface {
public:
virtual void draw() = 0;
};
class RectangleAdapter :public RectangleInterface {
public:
RectangleAdapter(double x,double y,double h,double w) : rect(x,y,x + w,y + h){}
void draw() {
cout << "RectangleAdapter::draw()" << '\n';
rect.reactangle_draw();
}
private:
Rectangle rect; //rect 作为成员变量调用它的函数
};
int main() {
RectangleAdapter adapter(1, 2, 4, 5);
adapter.draw();
RectangleInterface* ra = &adapter;
ra->draw();
return 0;
}
我们用 Rectangle rect;
成员变量的方式,调用它的构造函数和 draw()
函数,这样用 组合 的方式来替代继承的方式是比较常用的。