意图
将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
动机
有时,为复用而设计的工具箱不能够被复用的原因仅仅是因为它的接口与专业应用领域所需要的接口不匹配。
适用性
- 你想使用一个已经存在的类,而它的接口不符合你的需求。
- 你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
- (仅适用于对象Adapter)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。
类图
类适配器
对象适配器
例子场景
假设你缺鸭子对象,想用火鸡对象来冒充,火鸡对象的接口和鸭子对象接口不同。
实现
以对象适配器来实现
Duck.h
#pragma once
class Duck
{
public:
Duck();
virtual void quack() = 0;
virtual void fly() = 0;
};
Duck.cpp
#include "Duck.h"
Duck::Duck()
{
}
MallardDuck.h
#pragma once
#include "Duck.h"
class MallardDuck : public Duck
{
public:
MallardDuck();
void quack() override;
void fly() override;
};
MallardDuck.cpp
#include "MallardDuck.h"
#include <iostream>
MallardDuck::MallardDuck()
{
}
void MallardDuck::quack()
{
std::cout << "Quack" << std::endl;
}
void MallardDuck::fly()
{
std::cout << "I am flying" << std::endl;
}
Turkey.h
#pragma once
class Turkey
{
public:
Turkey();
virtual void gobble() = 0;
virtual void fly() = 0;
};
Turkey.cpp
#include "Turkey.h"
Turkey::Turkey()
{
}
WildTurkey.h
#pragma once
#include "Turkey.h"
class WildTurkey : public Turkey
{
public:
WildTurkey();
void gobble() override;
void fly() override;
};
WildTurkey.cpp
#include "WildTurkey.h"
#include <iostream>
WildTurkey::WildTurkey()
{
}
void WildTurkey::gobble()
{
std::cout << "Gobble gobble" << std::endl;
}
void WildTurkey::fly()
{
std::cout << "I am flying a short distance" << std::endl;
}
TurkeyAdapter.h
#pragma once
#include "Duck.h"
class Turkey;
class TurkeyAdapter : public Duck
{
public:
TurkeyAdapter(Turkey* pTurkey);
void quack() override;
void fly() override;
private:
Turkey* m_pTurkey;
};
TurkeyAdapter.cpp
#include "TurkeyAdapter.h"
#include "Turkey.h"
TurkeyAdapter::TurkeyAdapter(Turkey* pTurkey)
: m_pTurkey(pTurkey)
{
}
void TurkeyAdapter::quack()
{
m_pTurkey->gobble();
}
void TurkeyAdapter::fly()
{
for (int i = 0; i < 5; i++)
{
m_pTurkey->fly();
}
}
main.cpp
#include "MallardDuck.h"
#include "TurkeyAdapter.h"
#include "WildTurkey.h"
#include "Duck.h"
#include <memory>
#include <iostream>
using namespace std;
void testDuck(Duck* pDuck)
{
pDuck->quack();
pDuck->fly();
}
int main()
{
shared_ptr<Turkey> pTurkey = make_shared<WildTurkey>();
shared_ptr<Duck> pMallardDuck = make_shared<MallardDuck>();
shared_ptr<Duck> pTurkeyAdapter = make_shared<TurkeyAdapter>(pTurkey.get());
cout << "The Turkey says..." << endl;
pTurkey->gobble();
pTurkey->fly();
cout << endl;
cout << "The Duck says..." << endl;
testDuck(pMallardDuck.get());
cout << endl;
cout << "The TurkeyAdapter says..." << endl;
testDuck(pTurkeyAdapter.get());
return 0;
}