adapter为null_软件设计精要之——适配器(Adapter)模式
1、問題背景
Adapter模式解決的問題在生活中經(jīng)常會(huì)遇到:比如我們有一個(gè)Team為外界提供S類服務(wù),但是我們Team里面沒有能夠完成此項(xiàng)任務(wù)的member,然后我們得知有A可以完成這項(xiàng)服務(wù)(這項(xiàng)任務(wù)提供的服務(wù)重新取了個(gè)名字叫S’,并且他不對(duì)外公布他的具體實(shí)現(xiàn))。為了保證我們對(duì)外的服務(wù)類別的一致性(提供S服務(wù)),我們有以下兩種方式解決這個(gè)問題:
1)把A君直接招安到我們Team為我們工作,提供S服務(wù)的時(shí)候讓A君去辦就是了;
2)A君可能在別的地方有工作,并且不準(zhǔn)備接受我們的招安,于是我們Team可以想這樣一種方式解決問題:我們安排B君去完成這項(xiàng)任務(wù),并做好工作(Money)讓B君工作的時(shí)候可以向A君請(qǐng)教,因此B君就是一個(gè)復(fù)合體(提供S服務(wù),但是是A君的繼承弟子)。
實(shí)際上在軟件系統(tǒng)設(shè)計(jì)和開發(fā)中,這種問題也會(huì)經(jīng)常遇到:我們?yōu)榱送瓿赡稠?xiàng)工作購買了一個(gè)第三方的庫來加快開發(fā)。這就帶來了一個(gè)問題:我們?cè)趹?yīng)用程序中已經(jīng)設(shè)計(jì)好了接口,與這個(gè)第三方提供的接口不一致,為了使得這些接口不兼容的類(不能在一起工作)可以在一起工作了,Adapter模式提供了將一個(gè)類(第三方庫)的接口轉(zhuǎn)化為客戶(購買使用者)希望的接口。
在上面生活中問題的解決方式也就正好對(duì)應(yīng)了Adapter模式的兩種類別:類模式和對(duì)象模式。
2、模式示意圖
圖1、類的適配器模式示意圖
圖2、對(duì)象的適配器模式示意圖
3、代碼實(shí)現(xiàn)
3.1、Adapter(Class)
代碼實(shí)現(xiàn)如下:
//
//Adapter.h
//
#ifndef _ADAPTER_H_
#define _ADAPTER_H_
#include
using namespace std;
class Target
{
public:
Target();
virtual ~Target();
virtual void fnRequest();
protected:
private:
};
class Adaptee
{
public:
Adaptee();
~Adaptee();
void fnSpecificRequest();
protected:
private:
};
class Adapter:public Target,private Adaptee
{
public:
Adapter();
~Adapter();
void fnRequest();
protected:
private:
};
#endif //#ifndef _ADAPTER_H_
//
//Adapter.cpp
//
#include "Adapter.h"
Target::Target()
{
}
Target::~Target()
{
}
void Target::fnRequest()
{
cout<
}
Adaptee::Adaptee()
{
}
Adaptee::~Adaptee()
{
}
void Adaptee::fnSpecificRequest()
{
cout<
}
Adapter::Adapter()
{
}
Adapter::~Adapter()
{
}
void Adapter::fnRequest()
{
this->fnSpecificRequest();
}
//
//main.cpp
//
#include "Adapter.h"
void main()
{
Target * pTarget = NULL;
pTarget = new Adapter();
pTarget->fnRequest();
delete pTarget;
pTarget = NULL;
}
運(yùn)行結(jié)果如下:
3.2、Adapter(Object)
代碼實(shí)現(xiàn)如下:
//
//Adapter.h
//
#ifndef _ADAPTER_H_
#define _ADAPTER_H_
#include
using namespace std;
class Target
{
public:
Target();
virtual ~Target();
virtual void fnRequest();
protected:
private:
};
class Adaptee
{
public:
Adaptee();
~Adaptee();
void fnSpecificRequest();
protected:
private:
};
class Adapter:public Target
{
public:
Adapter(Adaptee* ade);
~Adapter();
void fnRequest();
protected:
private:
Adaptee* _ade;
};
#endif //#ifndef _ADAPTER_H_
//
//Adapter.cpp
//
#include "Adapter.h"
Target::Target()
{
}
Target::~Target()
{
}
void Target::fnRequest()
{
cout<
}
Adaptee::Adaptee()
{
}
Adaptee::~Adaptee()
{
}
void Adaptee::fnSpecificRequest()
{
cout<
}
Adapter::Adapter(Adaptee* ade)
{
_ade = ade;
}
Adapter::~Adapter()
{
delete _ade;
_ade = NULL;
}
void Adapter::fnRequest()
{
_ade->fnSpecificRequest();
}
//
//main.cpp
//
#include "Adapter.h"
void main()
{
Target * pTarget = NULL;
pTarget = new Adapter(new Adaptee);
pTarget->fnRequest();
delete pTarget;
pTarget = NULL;
}
運(yùn)行結(jié)果如下:
在Adapter模式中可以看到,類模式的Adapter采用繼承的方式復(fù)用Adaptee的接口,而在對(duì)象模式的Adapter中我們則采用組合的方式實(shí)現(xiàn)Adaptee的復(fù)用。
4、總結(jié)與討論
在Adapter模式的兩種模式中,有一個(gè)很重要的概念就是接口繼承和實(shí)現(xiàn)繼承的區(qū)別和聯(lián)系。接口繼承和實(shí)現(xiàn)繼承是面向?qū)ο箢I(lǐng)域的兩個(gè)重要的概念,接口繼承指的是通過繼承,子類獲得了父類的接口,而實(shí)現(xiàn)繼承指的是通過繼承子類獲得了父類的實(shí)現(xiàn)(并不統(tǒng)一共同接口)。在C++中的public繼承既是接口繼承又是實(shí)現(xiàn)繼承,因?yàn)樽宇愒诶^承了父類后既可以對(duì)外提供父類中的接口操作,又可以獲得父類的接口實(shí)現(xiàn)。當(dāng)然我們可以通過一定的方式和技術(shù)模擬單獨(dú)的接口繼承和實(shí)現(xiàn)繼承,例如我們可以通過private繼承獲得實(shí)現(xiàn)繼承的效果,通過純抽象基類模擬接口繼承的效果,在其他語言中可以用 interface來獲得專門的接口繼承。
總結(jié)
以上是生活随笔為你收集整理的adapter为null_软件设计精要之——适配器(Adapter)模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: wms地图绘制工具_GeoServer地
- 下一篇: java类的子类_java 查找类的所有