你的位置:首页 > ASP.net教程

[ASP.net教程]类适配器模式


适配器模式分为两种:类适配器模式和对象适配器模式。

类适配器模式需要用到多重继承机制(C++支持)。

然而Java/C#等语言不支持多重继承,那么可以采用对象适配器模式。

本文讲解类适配器模式。

背景

我们有一个绘图应用,可以在屏幕上绘制一些形状。该应用首先会获得该形状占据的区域大小,然后将形状绘制在此区域内。

clip_image001

客户端代码:

int main(int argc, char** argv){  Shape* shape = new Shape();  //获取该形状占据的矩形区域,以便于确定在哪个区域绘制该形状  Rect* boundingBox = shape->BoundingBox();  //绘制该形状  /****/  return 0;}

现在我们引用了一个第三方库,里面有TextView类。

clip_image001[4]

我们希望可以把TextView绘制在屏幕上,可是TextView类没有BoundingBox方法,因此我们不知道TextView占据的区域形状也就无法直接绘制该类。解决方案如下:

  • 修改TextView类的代码,以增加BoundingBox方法。(不可行,我们可能无法查看源码)
  • 用适配器模式。(对,下面我们来详细讲解)

适配器模式

适配器模式就像手机适配器(手机充电器)可以把220V的交流电转换为手机可以直接使用的5V直流电。我们先介绍下适配器模式中的几个术语:

  • 目标类(Target):5V直流电
  • 适配者(Adaptee): 220V交流电
  • 适配器(Adapter):手机充电器

我们知道客户端已经可以在屏幕上绘制Shape对象。然而不知道如何绘制TextView对象,因为它没有BoundingBox方法。我们考虑新建一个TextShape类,其含有BoundingBox方法。

Shape是目标类(Target)。

TextView是适配者(Adaptee)。

TextShape是适配器(Adapter)。

clip_image001[6]

C++实现代码

可以想象,适配器模式的关键是Adapter如何将Adaptee转换为Targe。如何转换取决于具体的应用。

Adapter代码:

Rect* TextShape::BoundingBox() const{  //一个中文字符占用2个相对宽度  //一个英文字符占用1个相对宽度  //这里为了简单起见,一律认为是1个相对宽度  float width = this->GetText().length();  float heigh = 1.0;  //高度和宽度都要乘上字体大小比例  return new Rect(      new Point(0, 0),       new Point(width * this->GetFontSize(), heigh * this->GetFontSize())    );}

客户端代码:

//采用类适配器模式的话,客户端代码会比较容易//如果采用对象适配器模式,客户端的代码会多一点int main(){  Shape* shape = new TextShape();  Rect* boundingBox = shape->BoundingBox();  return 0;}