一、功能
将一个类的接口转换成客户希望的另外一个接口,解决两个已有接口之间不匹配的问题。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
实际上在软件系统设计和开发中,这种问题也会经常遇到:我们为了完成某项工作购买了一个第三方的库来加快开发。这就带来了一个问题:我们在应用程序中已经设计好了接口,与这个第三方提供的接口不一致,为了使得这些接口不兼容的类(不能在一起工作)可以在一起工作了,Adapter模式提供了将一个类(第三方库)的接口转化为客户(购买使用者)希望的接口。
二、结构图
(1)class adapter
(2)object adapter
在Adapter模式的结构图中可以看到,类模式的Adapter采用继承的方式复用Adaptee的接口,而在对象模式的Adapter中我们则采用组合的方式实现Adaptee的复用。有关这些具体的实现和分析将在代码说明和讨论中给出。
三、实现
和其他很多模式一样,学习设计模式的重点是学习每种模式的思想,而不应拘泥于它的某种具体结构图和实现。因为模式是灵活的,其实现可以是千变万化的,只是所谓万变不离其宗。 在STL中大量运用了Adapter模式,象function adapter、iterator adpter,它们与这里说的adapter结构并不一样,但思想是一样的。具体的介绍可到侯捷网站上找相关文章,他讲得非常好。
四、示例代码
类模式的Adapter的C++代码
// 好比封装了第三方库
class Adaptee
{
public:
Adaptee() { }
virtual ~Adaptee() { }
public:
void SpecificRequest()
{
printf("[Adaptee] SpecificRequest()函数被调用. \n");
}
};
// 我们自己抽象类,上层调用该类的接口
class Target
{
public:
Target() { }
virtual ~Target() { }
public:
virtual void Reguest()
{
printf("[Target] Reguest()函数被调用. \n");
}
};
// 调用的实现类
class Adapter : public Target, private Adaptee
{
public:
Adapter() { }
~Adapter() { }
public:
virtual void Reguest()
{
printf("[Adapter] Reguest()函数被调用. \n");
SpecificRequest();
}
};
测试代码:
void AdapterDemo()
{
Target* pItem = new Adapter();
pItem->Reguest();
delete pItem;
}
对象模式的C++代码
// 好比封装了第三方库
class Adaptee
{
public:
Adaptee() { }
~Adaptee() { }
public:
void SpecificRequest()
{
printf("[Adaptee] SpecificRequest()函数被调用. \n");
}
};
// 我们自己抽象类,上层调用该类的接口
class Target
{
public:
Target() { }
virtual ~Target() { }
public:
virtual void Reguest()
{
printf("[Target] Reguest()函数被调用. \n");
}
};
class Adapter : public Target
{
public:
Adapter(Adaptee* pAda) : m_pAda(pAda) { }
~Adapter() { }
public:
virtual void Reguest()
{
printf("[Adapter] Reguest()函数被调用. \n");
m_pAda->SpecificRequest();
}
private:
Adaptee* m_pAda;
};
测试代码:
void AdapterDemo()
{
Adaptee adp;
Target* pItem = new Adapter(&adp);
pItem->Reguest();
delete pItem;
}