一、定义
适配器模式:将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。在适配器模式中,我们通过增加一个新的适配器类来解决接口不兼容的问题,使得原本没有任何关系的类可以协同工作。
三个角色:
Target目标角色:该角色定义把其它类转换为何种接口,也就是我们的期望接口。
Adaptee源角色:你想把谁转换成目标角色。
Adapter适配器角色:适配器模式的核心角色,其它两个角色都是已经存在的角色,而适配器角色是需要新建立的,它的职责非常简单,把源角色转换成目标角色,怎么转换?通过继承或类关联的方式。
二、类图
三、使用场景
如果需要将一些不同的两种类接和在一起,那就可以使用适配器模式。
- 适配器模式可以让两个没有任何关系得类在一起运行。
- 增加了类的透明性。我们访问的Target目标角色,但是具体的实现都委托给了源角色,而这些对高层次模块时透明的,也是它不需要关心的。
- 提高了类的复用度。
四、代码
实例:本地球员和外籍球员踢球。
1.球员基类
class Player {
public:
Player(string _name) {
this->name = _name;
}
virtual void Attack() = 0;
virtual void Defense() = 0;
protected:
string name;
};
2.各本地球员实现类
class Forwards :public Player {
public:
Forwards(string _name): Player(_name){}
virtual void Attack() {
cout << "前锋" << name << "进攻" << endl;
}
virtual void Defense() {
cout << "前锋" << name << "防守" << endl;
}
};
class Guards :public Player {
public:
Guards(string _name) : Player(_name) {}
virtual void Attack() {
cout << "后卫" << name << "进攻" << endl;
}
virtual void Defense() {
cout << "后卫" << name << "防守" << endl;
}
};
3.外籍球员实现类(Adaptee)
class ForeignCenter {
public:
void SetName(string _name) {
this->name = _name;
}
string GetName() {
return name;
}
void ForeignAttack() {
cout << "外籍中锋 " << name << " 攻击" << endl;
}
void ForeignDefense() {
cout << "外籍中锋 " << name << " 防守" << endl;
}
private:
string name;
};
4.适配角色(Adapter)目的:将外籍球员的函数功能通过适配器转换为Player子类功能,使Player对象可以调用ForeignCenter中的函数。
class Translator : public Player {
public:
Translator(string _name) :Player(_name) {
wjzf = new ForeignCenter;
wjzf->SetName(_name);
}
~Translator() {
if (wjzf != NULL) {
delete wjzf;
}
}
void Attack() {
wjzf->ForeignAttack();
}
void Defense() {
wjzf->ForeignDefense();
}
private:
ForeignCenter* wjzf;
};
5.客户端
int main() {
Player* aaa = new Forwards("111");
aaa->Attack();
aaa = new Guards("222");
aaa->Attack();
aaa = new Translator("333");
aaa->Attack();
aaa->Defense();
return 0;
}