适配器模式

发布时间 2023-11-29 23:54:55作者: blogzzt

1 模式动机

在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境中应用,但是新环境要求的接口是这些现存对象所不满足的。

如何应对这种“迁移的变化”?如何既能利用现有对象(老接口)的良好实现,同时又能满足新的应用环境所要求的接口?

Adapter模式主要应用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况",在遗留代码复角、类库迁移等方面非常有用。

 

2 模式定义

适配器模式(Adapter Pattern) :将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。

 

3 模式结构

适配器模式包含如下角色:

  • Target:目标抽象类 (新接口)
  • Adapter:适配器类
  • Adaptee:适配者类  (老接口)
  • Client:客户类

GoF 23定义了两种Adapter模式的实现结构:对象适配器和类适配器。但类适配器采用“多继承”的实现方式,一般不推荐使用。对象适配器来用“对象组合”的方式,更符合松耦合精神。

对象适配器:

../_images/Adapter.jpg

 

4 代码

#include <iostream>
#include "Adapter.h"
#include "Adaptee.h"
#include "Target.h"

using namespace std;

int main(int argc, char *argv[])
{
    Adaptee * adaptee  = new Adaptee();
    Target * tar = new Adapter(adaptee);
    tar->request();
    
    return 0;
}

 

///////////////////////////////////////////////////////////
//  Adapter.h
//  Implementation of the Class Adapter
///////////////////////////////////////////////////////////

#if !defined(EA_BD766D47_0C69_4131_B7B9_21DF78B1E80D__INCLUDED_)
#define EA_BD766D47_0C69_4131_B7B9_21DF78B1E80D__INCLUDED_

#include "Target.h"
#include "Adaptee.h"

class Adapter : public Target  // 继承
{

public:
    Adapter(Adaptee *adaptee);
    virtual ~Adapter();

    virtual void request();

private:
    Adaptee* m_pAdaptee;  // 组合

};
#endif // !defined(EA_BD766D47_0C69_4131_B7B9_21DF78B1E80D__INCLUDED_)

 

///////////////////////////////////////////////////////////
//  Adapter.cpp
//  Implementation of the Class Adapter
///////////////////////////////////////////////////////////

#include "Adapter.h"

Adapter::Adapter(Adaptee * adaptee){
    m_pAdaptee =  adaptee;
}

Adapter::~Adapter(){

}

void Adapter::request(){
    m_pAdaptee->specificRequest();
}

 

///////////////////////////////////////////////////////////
//  Adaptee.h
//  Implementation of the Class Adaptee
///////////////////////////////////////////////////////////

#if !defined(EA_826E6B4F_12BE_4609_A0A3_95BD5E657D36__INCLUDED_)
#define EA_826E6B4F_12BE_4609_A0A3_95BD5E657D36__INCLUDED_

class Adaptee
{

public:
    Adaptee();
    virtual ~Adaptee();

    void specificRequest();

};
#endif // !defined(EA_826E6B4F_12BE_4609_A0A3_95BD5E657D36__INCLUDED_)