ADAPTER模式可以将一个类的接口转换成另外一个接口,那样就可以使原来不兼容而不能一起工作的那些类可以一起工作。
ADAPTER模式也可以称为WRAPPER模式。
对于ADAPTER模式的简单包装功能,下面以STL中的一个例子来说明:
//下列代码片断摘自VC++6.0中的STACK
//可以在..VC98/Include/STACK中找到
template<class_Ty,class_C=deque<_Ty>>
classstack{
public:
//......
value_type&top()
{return(c.back());}
constvalue_type&top()const
{return(c.back());}
voidpush(constvalue_type&_X)
{c.push_back(_X);}
voidpop()
{c.pop_back();}
//......
protected:
_Cc;
};
可以看到stack就是deque的一个简单封装,也可以说stack是deque的一个适配器。通过这种简单的方法,就把deque的方法back(),push_back()和pop_back()给转换成了stack的top(),push()和pop()。
在上面的代码中只是用到了ADAPTER模式中的对象适配器,还有一种是类适配器。下面我就用一个C++的小例子来说明这两种适配器的区别和优缺点。
比如我们有一个视图系统,可以显示长方形、正方形和圆形,我们很容易利用COMPOSITE模式做出如下设计:
(关于COMPOSITE模式可以参考我的《重读《设计模式》之学习笔记(五)--我对COMPOSITE模式的理解》和《VISITOR模式--《敏捷软件开发》读书笔记(三)》)
classCShape
{
public:
~CShape(){};
virtualvoidDraw()=0;
};
//这里以输出一句话来代替具体的draw过程
classCRectangle:publicCShape
{
public:
voidDraw(){cout<<"Drawarectangle."<<endl;};
};
classCSquare:publicCShape
{
public:
voidDraw(){cout<<"Drawasquare."<<endl;};
};
classCCircle:publicCShape
{
public:
voidDraw(){cout<<"Drawacircle."<<endl;};
};
classCView:publicCShape
{
public:
~CView()
{
while(!m_vShape.empty())
{
CShape*pShape=(CShape*)m_vShape.back();
m_vShape.pop_back();
deletepShape;
}
}
voidDraw()
{
cout<<"Drawaview."<<endl;
for(vector<CShape*>::const_iteratorit=m_vShape.begin();it!=m_vShape.end();++it)
(*it)->Draw();
}
voidAddShape(CShape*pShape)
{
if(pShape)
m_vShape.push_back(pShape);
}
private:
vector<CShape*>m_vShape;
};
我们可以用下面的测试函数检验上面设计的正确性:
voidTest()
{
CViewview;
CRectangle*pRectangle=newCRectangle;
view.AddShape(pRectangle);
CSquare*pSquare=newCSquare;
view.AddShape(pSquare);
CCircle*pCircle=newCCircle;
view.AddShape(pCircle);
view.Draw();
}
现在,我们想在我们的这个视图系统里面添加对文本显示的支持。由于文本的显示跟图形的显示有很大差别,我们决定用别人已经开发好的类。比如下面的CText 类:
classCContext
{
public:
~CContext(){};
virtualvoidDrawText()=0;
};
//这里也以输出一句话来代替具体的draw过程
classCText:publicCContext
{
public:
voidDrawText(){cout<<"Drawatext."<<endl;};
};
由于类CText 的父类不是CShape,而且接口跟我们想要的接口不一样。为了在我们的系统中使用类CText 来显示文本,就可以使用ADAPTER模式创建一个类CText 的adapter,使CText 的接口适应我们已经写好的视图系统。
下面使用的是用类适配器:
classCShapeText:publicCShape,privateCText
{
public:
voidDraw(){DrawText();};
private:
voidDrawText()
{
CText::DrawText();
//这里可以改变父类的部分行为
cout<<"Itisatextadapter."<<endl;
}
};
类CShapeText就是类CText的类适配器,它从类CShape公有继承接口,而从类CText私有继承了实现。这样我们就可以把CShapeText加入到我们已经开发好的视图体统里面了。比如下面这个测试函数:
voidTest()
{
CViewview;
CRectangle*pRectangle=newCRectangle;
view.AddShape(pRectangle);
CSquare*pSquare=newCSquare;
view.AddShape(pSquare);
CCircle*pCircle=newCCircle;
view.AddShape(pCircle);
//在这里CShapeText跟其他CShape的子类一样的使用
//完全融入到已开发好的视图系统中
CShapeText*pText=newCShapeText;
view.AddShape(pText);
view.Draw();
}
下面用对象适配器来实现相同的功能:
classCShapeText:publicCShape
{
public:
CShapeText(CContext*pText){m_pText=pText;};
voidDraw(){m_pText->DrawText();};
private:
CContext*m_pText;
};
可以看到,代码中通过一个对象指针来调用相应的方法来实现将接口转换为我们希望得到的接口。下面是一个新的测试函数:
voidTest()
{
CViewview;
CRectangle*pRectangle=newCRectangle;
view.AddShape(pRectangle);
CSquare*pSquare=newCSquare;
view.AddShape(pSquare);
CCircle*pCircle=newCCircle;
view.AddShape(pCircle);
//这里的CShapeText一样可以很好的融入到已开发好的视图系统中
CText*pText=newCText;
CShapeText*pShapeText=newCShapeText(pText);
view.AddShape(pShapeText);
view.Draw();
}
通过上面的代码我们可以看出类适配器和对象适配器各自的优缺点:
类适配器:
优点:可以重新定义被适配的类的部分行为。
缺点:不能适配一个类以及它的子类。
对象适配器:
优点:可以适配一个类以及它的所有子类。
缺点:重新定义被适配的类的行为比较困难。
因此,我们可以得出结论:如果要适配一个类以及它的子类,或者只是简单的包装以转换接口,那就使用对象适配器;其他情况就用类适配器。
分享到:
相关推荐
java 汽车适配器(Adapter适配器模式) java 汽车适配器(Adapter适配器模式)
C#面向对象设计模式 Adapter 适配器模式 视频讲座下载
C#面向对象设计模式纵横谈(7):Adapter 适配器模式(结构型模式) 体验课程
在这里与各位分享本人从网络上下载的C#面向对象设计模式纵横谈系列视频,共有25节,除了第一节需要各位贡献一点资源分以作为对本人上传资源的回馈,后面的其他资源均不需要... 这是第7节:结构型模式Adapter 适配器模式
C#面向对象设计模式纵横谈(7):Adapter 适配器模式(结构型模式) (Level 300)
Adapter适配器模式在JavaScript设计模式编程中的运用分析_.docx
主要为大家详细介绍了Java设计模式之Adapter适配器模式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
主要介绍了Python设计模式编程中Adapter适配器模式的使用实例,一般来说适配器模式可以细分为类适配器和对象适配器模式,需要的朋友可以参考下
适配器模式的作用是解决两个软件实体间的接口不兼容的问题,在JavaScript尤其是AJAX方面比较常用,接下来看一下对Adapter适配器模式在JavaScript设计模式编程中的运用分析
走进设计模式之——适配器模式 (Adapter) 对应代码
主要介绍了Java 适配器模式(类适配器,对象适配器)优缺点对比的相关资料,java 适配器在基础知识中还是比较重要的,这里就说下如何使用,需要的朋友可以参考下
设计模式C++学习之适配器模式(Adapter)
一些书籍也称适配器模式为缺省适配器模式(Default Adapter Pattern) 。 适配器模式主要分 为三类: 类适配器模式、 对象适配器模式、 接口适配器模式。 以生活中手机充电为例来讲解适配器模式, 手机本身并不能...
C#设计模式之适配器模式应用实例
基于类的Adapter模式的一般结构如下:Adaptee类为Adapter的父类,Adaptee类为适配源,适配目标(接口)也是Adapter的父类;基于类的Adapter模式比较适合应用于Adapter想修改Adaptee的部分方法的情况。 基于对象的...
java设计模式之适配器模式,希望对大家有所帮助。
适配器模式 设计模式 Adapter 还请各位大S指教