适配器模式(Adapter),将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原来由于不兼容而不能一起工作的那些类可以一起工作。
适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况。
在Gof的设计模式中,对适配器模式讲了两种类型,类适配器模式和对象适配器模式,类适配器通过多重继承对一个接口与另外一个接口进行匹配,其他一些语言不支持多重继承,这里我们主要讲的是对象是适配器。
target.h
#pragma once
#include <iostream>
class Target
{
public:
virtual ~Target() {}
virtual void Request()
{
std::cout << "普通请求..." << std::endl;
};
};
adaptee.h
#pragma once
#include <iostream>
class Adaptee
{
public:
void SpecificRequest()
{
std::cout << "特殊请求..." << std::endl;
}
};
adapter.h
#pragma once
#include "target.h"
#include "adaptee.h"
class Adapter : public Target
{
public:
Adapter() : m_adaptee(new Adaptee())
{
}
~Adapter()
{
delete m_adaptee;
m_adaptee = nullptr;
}
void Request() override
{
m_adaptee->SpecificRequest();
}
private:
Adaptee *m_adaptee;
};
客户端:
#include "adapter.h"
int main()
{
Target *target = new Adapter();
target->Request();
getchar();
return 0;
}
运行结果:
特殊请求...
另外举了一个例子:姚明开始去NBA打球,位置是中锋,但是刚开始听不懂教练的英语安排,于是就请了一个翻译,将教练的安排转换成他能听懂的中文。这个英语翻译就是适配器。(臆造出来的场景,实际上可能有偏差,见谅)
player.h
#pragma once
#include <string>
class Player
{
public:
Player(const std::string &name) : m_name(name){}
virtual ~Player() {}
virtual void Attack() = 0;
virtual void Defence() = 0;
protected:
std::string m_name;
};
前锋forwads.h
#pragma once
#include "player.h"
#include <iostream>
class Forwards : public Player
{
public:
Forwards(const std::string &name) : Player(name){}
void Attack() override
{
std::cout << "前锋" << m_name << "进攻" << std::endl;
}
void Defence() override
{
std::cout << "前锋" << m_name << "防守" << std::endl;
}
};
后卫guards.h
#pragma once
#include "player.h"
#include <iostream>
class Guards : public Player
{
public:
Guards(const std::string &name) : Player(name){}
void Attack() override
{
std::cout << "后卫" << m_name << "进攻" << std::endl;
}
void Defence() override
{
std::cout << "后卫" << m_name << "防守" << std::endl;
}
};
外籍中锋foreignCenter.h:
外籍中锋的进攻和防守,说的话是他的母语。
#pragma once
#include <iostream>
#include <string>
class ForeignCenter
{
public:
ForeignCenter(const std::string &name) : m_name(name){}
std::string GetName() const
{
return m_name;
}
void SetName(const std::string &name)
{
m_name = name;
}
void ForeignAttack()
{
std::cout << "外籍中锋" << m_name << "进攻" << std::endl;
}
void ForeignDefence()
{
std::cout << "外籍中锋" << m_name << "防守" << std::endl;
}
private:
std::string m_name;
};
外籍中锋配个翻译translator.h:
#pragma once
#include "player.h"
#include "ForeignCenter.h"
#include <iostream>
class Translator : public Player
{
public:
Translator(const std::string &name) : Player(name)
{
m_foreignCenter = new ForeignCenter(name);
}
void Attack() override
{
std::cout << "外籍中锋" << m_name << "进攻" << std::endl;
}
void Defence() override
{
std::cout << "外籍中锋" << m_name << "防守" << std::endl;
}
private:
ForeignCenter *m_foreignCenter;
};
客户端main.cpp
#include "forwads.h"
#include "guards.h"
#include "translator.h"
int main()
{
Player *b = new Forwards("巴蒂尔");
b->Attack();
Player *m = new Guards("麦克格雷迪");
m->Attack();
Player *ym = new Translator("姚明");
ym->Attack();
ym->Defence();
getchar();
return 0;
}
运行结果:
前锋巴蒂尔进攻
后卫麦克格雷迪进攻
外籍中锋姚明进攻
外籍中锋姚明防守