背景:姚明刚开始在NBA需要翻译,将英语翻译为汉语
适配器模式(Adapter)
将一个类的接口转换成客户希望的另外一个接口。
Adapter模式使得原本由于接口不兼容而不能工作的那些类可以一起工作。
适配器模式解决的主要问题:需要的东西就在眼前,但不能马上使用它,短时间也没法改造它,想办法适配它。(笔记本电脑电源适配器)
刚开始让姚明学英语,或者教练,球员学习汉语都不现实。翻译工作。(翻译即相当于适配器)
1.在软件开发中,系统的数据和行为都正确,但接口不符和时,我们应该考虑使用适配器,目的是使控制范围之外的一个原有的对象与某个接口匹配。适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况。
类适配器模式和对象适配器模式,主讲对象适配器模式。(C++支持多重继承,java,C#等不行)
UML类图
2.何时使用:在想使用一个已经存在的类,但如果它的接口,也就是它的方法和你的要求不相同时,应该考虑使用适配器模式
两个类所作的事情相同或相似,但是具有不同的接口时要使用它。而且由于类都共享同一个接口,客户端代码统一调用同一个接口,更简单,直接,紧凑。
3.一般在后期维护时使用,前期就统一接口,前期不统一就应该重构。(即双方都不太容易修改的时候使用适配器)。前期可以的特殊情况公司设计系统考虑使用第三方开发的组件,而三方组件的接口与我们自己的不相同的,可以考虑使用。
c++代码实现
//球员
class Player {
private:
string m_name;
public:
Player(string str)
{
m_name = str;
}
virtual void Attack() { cout << "Player::Attack" << endl; }
virtual void Defense() { cout << "Player::Defense" << endl; }
};
//后卫中锋前锋
class Forwards :public Player {
public:
Forwards(string str):Player(str)
{
}
virtual void Attack() { cout << "Forwards::Attack" << endl; }
virtual void Defense() { cout << "Forwards::Defense" << endl; }
};
class Center :public Player {
public:
Center(string str) :Player(str)
{
}
virtual void Attack() { cout << "Center::Attack" << endl; }
virtual void Defense() { cout << "Center::Defense" << endl; }
};
class Guards :public Player {
public:
Guards(string str) :Player(str)
{
}
virtual void Attack() { cout << "Guards::Attack" << endl; }
virtual void Defense() { cout << "Guards::Defense" << endl; }
};
//外籍中锋
class ForeignCenter {
private:
string m_name;
public:
void setName(string str) { m_name = str; }
string getName() { return m_name; }
void jingong() { cout << "ch jingong" << endl; }
void fangyu() { cout << "ch fangyu" << endl; }
};
//翻译者类
class Translator :public Player {
private:
ForeignCenter* fc;
public:
Translator(string str) :Player(str) //声明并实例化一个内部的外籍中锋对象,表明翻译者翻译谁
{
fc = new ForeignCenter();
fc->setName(str);
}
virtual void Attack() //翻译者进行翻译
{
cout << "Translator:Attack" << endl;
fc->jingong();
}
virtual void Defense()
{
cout << "Translator::Defense" << endl;
fc->fangyu();
}
};
int main()
{
std::cout << "Hello World!\n";
Player* b = new Forwards("zzz");
b->Attack();
Player *c = new Guards("sss");
c->Defense();
//Player* ym = new Center("yaoming");
//ym->Attack(); //姚明刚开始不懂英语
//ym->Defense();
Player* ym = new Translator("yaoming");
ym->Attack();
ym->Defense();
}
4.适配器模式的.Net使用:
5.扁鹊的三兄弟的医术,老大治病于病发之前,老二病初,老三病危。实先预防接口不同的问题,不匹配的问题就不会发生。在有小的接口不统一时,及时重构,问题不至于扩大。只有碰到无法改变原有代码和设计的情况时才考虑适配。事后控制不如事中控制,事中控制不如事前控制。