介绍
适配器模式就是把一个接口或类转换成其他的接口或类。该模式隶属于 {结构型模式}
- Target目标角色
该角色定义把其他类转换为何种接口,也就是我们的期望接口。
- Adaptee源角色
它是已经存在的、 运行良好的类或对象。
- Adapter适配器角色
适配器模式的核心角色,其他两个角色都是已经存在的角色,而适配器角色是需要新建立的,它的职责非常简单:把源角色转换为目标角色。
优点: 适配器模式可以让两个没有任何关系的类在一起运行;增加了类的透明性;提高了类的复用度;灵活性非常好
应用: 有动机修改一个已经投产中的接口时
适配器模式最好在详细设计阶段不要考虑它, 它不是为了解决还处在开发阶段的问题,而是解决正在服役的项目问题。 适配器模式是一个补偿模式, 或者说是一个“补救”模式,通常用来解决接口不相容的问题
UML类图
简单示例:
#ifndef SIMPLE_ADAPTER_H
#define SIMPLE_ADAPTER_H
#include <iostream>
using namespace std;
/**
* @brief The Target class
* Target ( 这是客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口)
*/
class Target
{
public:
void virtual Request()
{
cout<<" 普通请求 "<<endl;
}
};
/**
* @brief The Adaptee class
* 需要适配的类
*/
class Adaptee
{
public:
void specificRequest()
{
cout<<"特殊请求"<<endl;
}
};
class Adapter : public Target
{
public:
Adapter()
{
mptee = new Adaptee;
}
void Request() override
{
mptee->specificRequest();
}
private:
Adaptee *mptee;
};
#endif // SIMPLE_ADAPTER_H
客户端调用:
Target *target = new Adapter;
target->Request();
大话设计模式 NBA示例:
UML类图:
#ifndef NBA_ADAPTER_H
#define NBA_ADAPTER_H
#include <iostream>
using namespace std;
/**
* @brief The Player class
* 球员抽象类
*/
class Player
{
public:
Player(string name = " ")
{
m_name = name;
}
string getName() const
{
return m_name;
}
void virtual attack() = 0;
void virtual defense() = 0;
private:
string m_name;
};
/**
* @brief The Forwards class
* 前锋
*/
class Forwards : public Player
{
public:
Forwards(string name)
:Player(name)
{
}
void attack() override
{
cout<<"前锋 ["<<getName()<<"] 进攻"<<endl;
}
void defense() override
{
cout<<"前锋 ["<<getName()<<"] 防守"<<endl;
}
};
/**
* @brief The Center class
* 中锋
*/
class Center : public Player
{
public:
Center(string name)
:Player(name)
{
}
void attack() override
{
cout<<"中锋 ["<<getName()<<"] 进攻"<<endl;
}
void defense() override
{
cout<<"中锋 ["<<getName()<<"] 防守"<<endl;
}
};
/**
* @brief The Guards class
* 后卫
*/
class Guards : public Player
{
public:
Guards(string name)
:Player(name)
{
}
void attack() override
{
cout<<"中锋 ["<<getName()<<"] 进攻"<<endl;
}
void defense() override
{
cout<<"中锋 ["<<getName()<<"] 防守"<<endl;
}
};
/**
* @brief The ForeignCenter class
* 外籍中锋
*/
class ForeignCenter
{
public:
void setFName(string &name)
{
m_name = name;
}
string getFName() const
{
return m_name;
}
void attack()
{
cout<<"外籍中锋 ["<<m_name<<"] 进攻"<<endl;
}
void defense()
{
cout<<"外籍中锋 ["<<m_name<<"] 防守"<<endl;
}
private:
string m_name;
};
/**
* @brief The Translator class
* 翻译者(适配器)
*/
class Translator : public Player
{
public:
Translator(string name)
:Player(name)
{
m_fcp = new ForeignCenter;
m_fcp->setFName(name);
}
void attack() override
{
cout<<"翻译说:"<<endl;
m_fcp->attack();
}
void defense() override
{
cout<<"翻译说:"<<endl;
m_fcp->defense();
}
private:
ForeignCenter *m_fcp;
};
#endif // NBA_ADAPTER_H
客户端调用:
Player *p1 = new Forwards("巴蒂儿");
p1->attack();
Player *p2 = new Center("麦克格雷迪");
p2->defense();
/* 姚明熟练英语
Player *p3 = new Guards("姚明");
p3->attack();
*/
/*
假设姚明刚到NBA,不熟练英语
*/
Player *p3 = new Translator("姚明");
p3->attack();
运行结果: