适配器模式(Adapter),将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的哪些类可以一起工作。
系统的数据和行为都正确,但接口不符时,我们应该考虑用适配器,目的是使控制范围之外的一个原有对象与某个接口匹配。适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况。
适配器模式例子
系统的数据和行为都正确,但接口不符时,我们应该考虑用适配器,目的是使控制范围之外的一个原有对象与某个接口匹配。适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况。
在GoF的设计模式中,对适配器模式讲了两种类型,类适配器模式和对象适配器模式。类适配器模式通过多重继承对一个接口与另一个接口进行匹配。
何时使用适配器:使用一个已经存在的类,但如果它的接口,也就是它的方法和你的要求不相同,就应该考虑用适配器模式。两个类所做的事情相同和相似,但是具有不同的接口时要使用它。而且类都共享同一个接口,使得客户端代码可以统一调用同一接口就可以,下面的例子中Target.request()就是同一个接口,这样可以更简单、直接、紧凑。
适配器模式原型
#include <stdio.h>
//Target(这是客户所期待的接口。目标可以使具体的或抽象的类,也可以使接口)代码如下
class Target
{
public:
virtual void Request()
{
printf("普通请求!\n");
}
};
//Adaptee(需要适配的类)
class Adaptee
{
public:
void SpecificRequest()
{
printf("特殊请求!\n");
}
};
//Adapter(通过在内部包装一个Adaptee对象,把源接口转换成目标接口)
class Adapter : public Target
{
private:
Adaptee adaptee; //建立一个私有的Adaptee对象
void Request()
{
adaptee.SpecificRequest();//这样就可以把表面上调用Request()方法变成实际调用SpecificRequest();
}
};
//测试代码如下
int main()
{
Target *target;
Target target1;
Adapter adapter1;
target = &target1;
target->Request(); //未使用适配器前的request
target = &adapter1;
target->Request(); //使用适配器后的request
return 1;
}
适配器模式例子
#include <string>
using namespace std;
//适配器模式例子,因为姚明刚去NBA不会英语,所以需要一个翻译作为适配器,与其他球员及教练沟通
//所有的球员,不论中锋、前锋、后卫都是球员,应该是一个统一的抽象类,也就是客户期待的接口
//球员
class Player
{
public:
string name;
public:
Player(string name)
{
this->name = name;
}
virtual void Attack() = 0;
virtual void Defense() = 0;
};
//各种具体球员。
//前锋
class Forwords : public Player
{
public:
Forwords(string name): Player(name)
{
}
public:
void Attack()
{
printf("前锋%s进攻 \n",name);
}
void Defense()
{
printf("前锋%s防守 \n",name);
}
};
//后位
class Guards : public Player
{
public:
Guards(string name): Player(name)
{
}
public:
void Attack()
{
printf("后卫%s进攻 \n",name);
}
void Defense()
{
printf("后卫%s防守 \n",name);
}
};
//中锋
class Center : public Player
{
public:
Center(string name) : Player(name)
{
}
public:
void Attack()
{
printf("中锋%s进攻 \n",name);
}
void Defense()
{
printf("中锋%s防守 \n",name);
}
};
//外籍中锋
class ForeignCenter : public Player
{
public:
ForeignCenter(string name): Player(name)
{
}
public:
void Attack()
{
printf("外籍中锋 %s 进攻 \n",name);
}
void Defense()
{
printf("外籍中锋 %s 防守 \n",name);
}
};
//翻译者 ,相当于适配器
class Translator : public Player
{
private:
ForeignCenter wjzf; //声明并实例化一个内部“外籍中锋”对象,表明翻译者与外籍球员有关联
public:
Translator(string name) : wjzf(name),Player(name)
{
}
public:
void Attack()
{
wjzf.Attack(); //翻译者告诉外籍中锋"Attack"
}
void Defense()
{
wjzf.Defense(); //翻译者告诉外籍中锋"防守"
}
};
//测试函数
int main()
{
Player *b;
Forwords forword("巴蒂尔");
Guards guards("麦迪");
Translator translator("姚明");
b = &forword;
b->Attack();
b = &guards;
b->Attack();
b = &translator;
b->Attack();
b->Defense();
return 1;
}