适配器模式:将一个类的结构转换成客户希望的另外一个借口。适配器模式使得原本由于借口不兼容而不能一起工作的那些类可以一起工作。在软件开发过程中,如果系统的数据和行为都正确,但借口不符时我们应该考虑适配器模式。主要用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况。
其一般形式为:一个目标类(Target,即客户期望的接口),一个需要被适配的类(Adaptee,原接口),一个适配器类(Adapter,通过内部包装一个Adaptee对象,把原接口转换成目标接口),其结构图如下:
代码示例如下:
#include<iostream>
#include<string>
using namespace std;
class Target {//客户所期待的接口,可以是具体的或者抽象的类,也可以是接口
public:
virtual void request()
{
cout << "普通请求" << endl;
}
};
class Adaptee {//需要适配的类,其调用的是另一个函数
public:
void specialRequest()//特殊请求
{
cout << "特殊请求" << endl;
}
};
//适配器类,内部包含一个Adaptee对象,通过这个对象再去调用原来的请求
class Adapter :public Target {
public:
Adapter()
{
this->adaptee = new Adaptee();
}
void request() {
this->adaptee->specialRequest();
}
private:
Adaptee* adaptee;//内部包装一个Adaptee对象
};
//姚明在NBA打球,刚开始听不懂英语进攻和防守,需要“翻译”,使用适配器模式
class Player {//目标类
protected:
string name;
public:
Player() {};
Player(string str)//提供有参构造,系统不会提供默认构造了,需要自定义
{
this->name = str;
}
virtual void Attack() {};
virtual void Defense() {};
};
//前锋
class Forwards :public Player {
public:
Forwards(string name)
{
this->name = name;
}
void Attack()
{
cout << "前锋"<<name << "进攻" << endl;
}
void Defense()
{
cout << "前锋" << name << "防守" << endl;
}
};
//中锋
class Center :public Player {
public:
Center(string name)
{
this->name = name;
}
void Attack()
{
cout << "中锋" << name << "进攻" << endl;
}
void Defense()
{
cout << "中锋" << name << "防守" << endl;
}
};
//后卫
class Guards :public Player {
public:
Guards(string name)
{
this->name = name;
}
void Attack()
{
cout << "后卫" << name << "进攻" << endl;
}
void Defense()
{
cout << "后卫" << name << "防守" << endl;
}
};
//外籍中锋
class ForeignCenter {//需要适配的类
private:
string name;
public:
string getName()
{
return this->name;
}
void setName(string value)
{
this->name = value;
}
void foreAttack()
{//外籍球员只听得懂自己语言的指令
cout << "外籍中峰" << this->name << "进攻" << endl;
}
void foreDefense()
{//外籍球员只听得懂自己语言的指令
cout << "外籍中峰" << this->name << "防守" << endl;
}
};
//适配器类(翻译),在内部实例化一个需要适配的类的对象,表明适配器与被适配的对象之间的联系
class Translator :public Player {
public:
Translator(string value)
{
forecenter = new ForeignCenter();
forecenter->setName(value);
}
void Attack()
{
this->forecenter->foreAttack();
}
void Defense()
{
this->forecenter->foreDefense();
}
private:
ForeignCenter* forecenter;
};
int main()
{
Target* target = new Adapter();
target->request();//调用特殊请求
Player* player_bdi = new Forwards("巴蒂尔");
player_bdi->Attack();
Player* player_mike = new Center("麦克格雷迪");
player_mike->Defense();
Player* player_ym = new Translator("姚明");
player_ym->Defense();
player_ym->Attack();//姚明通过“翻译”进攻和防守
system("pause");
return 0;
}