Adapter(适配器)模式解决的是接口兼容的问题。
举现实中的例子来说,墙上只提供了三相的插座,我们的电器却使用了二相的插头。我们要怎样使电器可以工作?很简单,买一个二相转三相的适配器就可以了。
在开发当中,我们常常遇到这样的问题:当我们要使用一份代码(或许是SDK提供的)时,发现它与我们已有的架构不兼容。
例如
我们在制作一个绘图软件,其中定义了很多形状:Circle, Ellipse ......,这些类都有一个共同的祖先:Shape。
public abstract class Shape
{
int m_Width;
public virtual int Width
{
get { return m_Width;}
set { m_Width = value;}
}
}
public class Circle : Shape
{
}
当我们想要添加一个矩形类(Rectangle)时,发现SDK为我们提供了一个Rectangle类,它与我们已经写好的形状类型有很多共通之处,但由于它并非由Shape派生而来,我们不能自由的在我们的架构中使用它。同时从Shape派生一个Rectangle类的工作量很大,是不值得的。
于是我们决定给Rectangle类加一个外壳:
public class MyRectangle : Shape
{
private Rectangle m_Rectangle;
public MyRectangle()
{
m_Rectangle = new Rectangle();
}
public override int Width
{
get
{
return m_Rectangle.Width;
}
set
{
m_Rectangle.Width = value;
}
}
}
这样我们就可以使用Rectanlge类了。
Adapter也不是万能的,尤其是在遇到一些封装很严密的类的时候,我们可能会发现虽然我们可以通过Adapter将它的属性映射到我们需要的类型中,却很难根据需要对它做扩充,因为我们需要更改的那部分逻辑被通过某种手段(只读属性、私有成员,等等)隐藏起来了。
所以,Adapter模式的使用需要慎重,尽量在使用前确定它可以很好的工作,而非到发现无法继续的时候推翻重来(往事不堪回首啊……)。