把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹配而无法一起工作的两个类能够在一起工作。
- 类的适配器模式
- 对象的适配器模式
- 对象适配器
在上图中可以看出:
- 冲突:
Target 期待调用 Request 方法,而 Adaptee 并没有(这就是所谓的不兼容了)。
- 解决方案:
为使 Target 能够使用 Adaptee 类里的 SpecificRequest 方法 **,故提供一个中间环节 Adapter 类,把 Adaptee 的 API 与 Target 的 API 衔接起来 **(适配)
示例代码场景:
各个地方的家庭用电不同,插座的电压不同;需要接适配器后适应不同的电压;
比如手机充电不可能进入手机中的电压是220V吧。所以适配器就发挥乐重要作用
插座类
class Plug
{
public:
Plug() {
cout << "Plug构造函数" << endl;
}
virtual ~Plug() {
cout << "Plug析构函数" << endl;
}
virtual int outputV() = 0;
};
//国内插座需要220V
class Myplug:public Plug
{
public:
Myplug() {
cout << "Myplug构造函数" << endl;
}
~Myplug() {
cout << "Myplug析构函数" << endl;
}
int outputV() override {
return getOutput220V();
}
int getOutput220V(void) {
return 220;
}
};
目标类 有5V电压的接口
class Target
{
public:
Target(){
cout << "Target构造函数" << endl;
}
virtual ~Target(){
cout << "Target析构函数" << endl;
}
//基类纯虚函数接口,子类负责重写
virtual int getOutput5V() = 0;
};
电源适配器类,用于适配不同的电压
class PowerAdapter:public Target
{
public:
PowerAdapter() {
cout << "PowerAdapter构造函数" << endl;
}
~PowerAdapter() {
cout << "PowerAdapter析构函数" << endl;
}
//多态接口,基类指针指向子类
void setPlug(Plug* plug) {
this->plug_ = plug;
}
//适配器处理适配的业务逻辑
int getOutput5V() override {
int v = plug_->outputV();
int div = v / 5;
cout << "适配器开始工作 " << endl;
cout << v << " change " << v / div << endl;
cout << "现在的电压为: ";
return v / div;
}
private:
Plug* plug_=nullptr;
};
main函数入口
int main()
{
Myplug* myPlug = new Myplug;
PowerAdapter* powerAdapter = new PowerAdapter;
powerAdapter->setPlug(myPlug);
cout << powerAdapter->getOutput5V() << endl;
delete myPlug;
myPlug = nullptr;
delete powerAdapter;
powerAdapter = nullptr;
return 0;
}
- 类适配器
适配器类继承需求接口和适配者,然后重新实现需求接口,在需求接口中调用适配者提供的接口
C++多继承的使用
class PowerAdapter :public Target, public Myplug
{
public:
PowerAdapter() {
cout << "PowerAdapter构造函数" << endl;
}
~PowerAdapter() {
cout << "PowerAdapter析构函数" << endl;
}
//适配器处理适配的业务逻辑
int getOutput5V() override {
int v = outputV();
int div = v / 5;
cout << "适配器开始工作 " << endl;
cout << v << " change " << v / div << endl;
cout << "现在的电压为: ";
return v / div;
}
private:
Plug* plug_ = nullptr;
};
int main()
{
PowerAdapter* powerAdapter = new PowerAdapter;
cout << powerAdapter->getOutput5V() << endl;
delete powerAdapter;
powerAdapter = nullptr;
return 0;
}
总结:
优点:
- ·能提高类的透明性和复用性,现有的类会被复用但不需要改变。
- ·目标类和适配器类解耦,可以提高程序的扩展性。
- ·在一般业务场景中符合开闭原则。
缺点:
- ·在适配器代码编写过程中需要进行全面考虑,可能会增加系统复杂度。
- ·增加代码阅读难度,过多使用适配器会使系统代码变得凌乱。