Adapter(适配器)模式
意图:Adapter模式使得因为接口不兼容而不能在一起工作的类可以一起工作。
假如有这样的情况我们需要设计一组几何形状(line, square, circle)来画出它们的形状和颜色。我们定义了一个抽象类shape,其中定义了display() 和 setColour()两个虚函数用来画出特定的几何形状和给该几何形状设置颜色。
例如:
class shape{ //抽象类shape
public:
shape();
virtual void display() const = 0;
virtual void setColour const = 0;
};
当我们从shape派生出line类和square类后我们就可以改写基类(shape)的成员函数,从而实现我们的画图、添色功能。
例如:
class line : public shape{ //实现类line
public:
virtual void display();
virtual void setColour();
};
void line::display() const
{
//do something
}
void line::setColour() const
{
//do something
}
class square : public shape{ //实现类square
public:
virtual void display();
virtual void setColour();
};
void square::display()
{
//do something
}
void square::setColour()
{
//do something
}
到目前为止我们进行的很顺利,接下来需要依样来实现circle的功能,此时可能有些卡壳了,因为相对于一条线或一个四边形来说,一个圆的某些实现要复杂的多,这时人的懒惰就表现了出来,于是我们到处找看有没有已经写好的代码可以用来copy。最后终于找到了一个,但是他的样子好像有点怪:
class X_circle{ //一个定义好的能实现圆的display()和setColour()操作的类
public:
X_circle();
void X_display();
void X_setColourt();
};
void X_circle::X_display()
{
//do something
}
void X_circle::X_setColourt()
{
//do something
}
这是一个已经实现好的,里面有好些复杂的算法是需要花费我们大量时间去写得。可是他并不能很融洽的在我们的继承体系里很好的工作。首先他的名字就和我们的不符,如果我们硬性的把X_circle改成circle的话,那么我么需要改动好多次,出错的几率太大。况且如果我们看不到源代码怎么办呢。
此时我们有一个变通的方法:我们依然从shape继承一个circle类,此时我们组合X_circle类,在circle类里实例化一个X_circle类的对象作为circle的私有成员,然后我们在circle类的方法里调用X_circle类的方法,这样我们就很好的利用了现有的X_circle类来为我们工作。不知不觉我们实现了Adapter模式,你体会到了么?
代码如下:
class circle : public shape{ //实现类circle
public:
circle(X_circle *cir);
virtual void display();
virtual void setColour();
private:
X_circle _circle;
};
circle::circle(X_circle &cir) //构造函数,用X_circle类的对象初始化circle类的数据成员
{
_circle = cir;
}
void circle::display()
{
_circle.X_display(); //用X_cirlce类的成员函数实现派生类circle的display()
}
void circle::setColour()
{
_circle.X_setColourt(); //用X_cirlce类的成员函数实现派生类circle的display()
}
看起来很简单,或许以前我们多次用过这样的方法。确实很简单,这就是Adapter模式。关于Adapter在《设计模式:可复用面向对象软件的基础》一书中有详细的介绍。这本书我现在依然看不大懂。写得不对之处请大家严厉批评指正。J