适配器类

本文深入探讨了适配器模式的概念、适用场景、实现方式及其在实际编程中的应用。通过具体代码实例,展示了如何使用适配器模式解决接口不兼容的问题,以及其在不同场景下的灵活运用。
 

Adapter:适配器模式;

意图:把一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以相互协调一起工作;简单地理解就是对现存的、可以复用的类加以抽象和封装,并对外提供一致的访问接口,或者是创建一些可以复用的、相互之间毫不相关的、可以相互协同工作的类;适配器类位于待复用类与用户自定义接口类之间,充当一个屏蔽待复用类接口的一个适配层;

适用性:

1、你想使用一个已经存在的类,而它的接口规范不符合你的需求;

2、你想创建一个可以复用的类,该类可以与其它不相关的类或不可预见的类(即:那些接口可能不一定兼容)协同工作;

3、(仅适用于对象Adapter)你想使用一些已经存在的类,但是不可能对每一个都进行子类化以匹配它们的接口;对象适配器可以适配它们的父类接口;

适配器类有两种实现方式:聚合方式和继承方式;

结构图:

应用:
#ifndef _ADAPTER_H_
#define _ADAPTER_H_

#include <iostream>
#include <string>

using namespace std;

/*
一个已知的类Adaptee,想使用这个类的接口来执行一些任务,但是这个类提供的接口没有一个是我想使用的接口,也就是说,
这个类提供的接口规范跟我自定义类的接口规范不一致,或者说这个类的接口与我现在的应用之间有冲突,但是又想使用这
个类提供的接口来完成我的任务,那么这个时候可以使用适配器模式定义一个适配器类Adapter,以对这个类的接口进行转换,
把这个类的接口转换城我要求的规范,即:对类Adaptee再进行一次抽象封装;
适配器类位于用户自定义接口类与已知的想使用的接口类之间,适配器类在用户自定义接口类与已知想调用的接口类之间提
供了一个适配层,这个适配层屏蔽了接口规范,使互不兼容的接口类之间可以相互协调工作;
*/
class Adaptee   //已知的类,准备复用的类;
{
  public:
    Adaptee(void)
    {
      cout << "call Adaptee()" << endl;
    }

    ~Adaptee(void)
    {
      cout << "call ~ Adaptee()" << endl;
    }

  public:
    int SpecificRequest(const string& strName)   //想调用这个接口,但是这个接口的规范不符合我自定义类的接口规范;
    {
      cout << "I am a interface of class " << strName << endl;
      return 0;
    }
};

//适配器类的纯虚基类,也是用户自定义的目标类,需要实际应用的类;
class Target
{
  public:
    Target(void){};
    virtual ~Target(void){};

    virtual int Request(const string& strName) = 0;
};

//适配器类:聚合的方式实现接口的转换;
class Adapter: public Target
{
  private:
    Adaptee m_oAdaptee;

  public:
    Adapter(void)
    {
      cout << "call Adapter()" << endl;
    }

    virtual ~Adapter(void)
    {
      cout << "call ~ Adapter()" << endl;
    }

    virtual int Request(const string& strName)
    {
      int nReturn = 0;
      nReturn = this->m_oAdaptee.SpecificRequest(strName);
      return nReturn;
    }
};

//适配器类:继承的方式实现接口的转换;

class Adapter: public Target, public Adaptee
{
  public:
    Adapter(void)
    {
      cout << "-----call Adapter()" << endl;
    }

    virtual ~Adapter(void)
    {
      cout << "-----call ~ Adapter()" << endl;
    }

    int Request(const string& strName)
    {
      int nReturn = 0;
      nReturn = this->SpecificRequest(strName);
      return nReturn;
    }
};

//用户自定义的应用接口类;

class AdapterApplication
{
  private:
    Target* m_lpTarget;

  public:
    AdapterApplication(void)
    {
      this->m_lpTarget = NULL;
      cout << "call AdapterApplication()" << endl;
    }

    ~AdapterApplication(void)
    {
      if(this->m_lpTarget)
      {
        delete this->m_lpTarget;
      }
      cout << "call ~ AdapterApplication()" << endl;
    }

    int Request(const string& strName)
    {
      if(!(this->m_lpTarget))
      {
        this->m_lpTarget = new Adapter();
      }

      if(!(this->m_lpTarget))
      {
        return -1;
      }
      return this->m_lpTarget->Request(strName);
    }
};

#endif
#include "Adapter.h"

int main(int argc, char** argv)
{
  AdapterApplication oAdapterApplication;

  oAdapterApplication.Request("AdapterApplication");

  return 0;
}

针对适配器模式做一个形象的比喻:

现在市面上有很多转换线,用于不同通讯接头之间的转换,比如:

RS232   ----->  线路转换器  -----> USB -----> 计算机;

RJ-45   ----->  线路转换器  -----> USB -----> 计算机;

PS/2    ----->  线路转换器  -----> USB -----> 计算机;

外接光驱----->  线路转换口  -----> USB -----> 计算机;

移动硬盘----->  线路转换口  -----> USB -----> 计算机;

其中,

USB口就相当于本模式里的应用样例中的Target类:适配器类的纯虚基类;

线路转换器和线路转换口就相当于本模式里的应用样例中的适配器类Adapter,执行接口转换任务;

RS232口、RJ-45口、PS/2口、外接光驱以及移动硬盘就相当于本模式里的应用样例中的待复用的类Adaptee,实现具体的功能;

计算机就相当于本模式里的应用样例中的AdapterApplication类,是转换后的、需要被客户使用的、也是客户希望看到的接口的实际应用者,即:客户;

 

 

#ifndef _ADAPTER_H
#define _ADAPTER_H

#include <iostream>
#include<string>
using namespace std;

//原先的类,只不过该类的接口不满足现在的需求
class Adaptee
{
public:
 Adaptee()
 {
  cout<<"call Adaptee"<<endl;
 }
 ~Adaptee()
 {
  cout<<"call ~Adaptee"<<endl;
 }
public:
 //想调用这个接口,但是这个接口不满足自定义类的接口规范
 int SpecificRequest(const string&strName)
 {
  cout<<"I am a interface of class"<<strName<<endl;
  return 0;
 }
}

//用户自定义类,用于适配器类的纯虚类
class Target
{
public:
 Target()
 {
 
 }
 virtual ~Target()
 {
 
 }
 virtual int Request(const string& strName)=0;
};

//适配器类:组合的方式实现接口的转换
class Adapter:public Target//继承自用户自定义类
{
private:
 Adaptee m_oAdaptee; //原先的类
public:
 Adapter();
 {
  cout<<"call Adapter()"<<endl;
 }
 virtual ~Adapter()
 {
  cout<<"call ~Adapter()"<<endl;
 }
 virtual int Request(const string&strName)
 {
  int nReturn=0;
  nReturn=this->m_oAdaptee.SpecificRequest(strName); //调用原先的类中的不满足现在需求的函数
  return nReturn;
 }
};

//适配器类:继承的方式实现接口的转换
class Adapter:public Target,public Adaptee
{
public:
 Adapter()
 {
  cout<<"call Adapter()"<<endl;
 }
 virtual ~Adapter()
 {
  cout<<"call ~Adapter"<<endl;
 }
 int Request(const string& strName)
 {
  int Request(const string& strName)
  {
   int nReturn=0;
   nReturn=this->SpecificRequest(strName);
   return nReturn;
  }
 }
};

//用户自定义的应用接口类
class AdapterApplication
{
private:
 Target* m_lpTarget; //用户自定义类
public:
 AdapterApplication()
 {
  this->m_lpTarget=NULL;
  cout<<"call AdapterApplicatiion"<<endl;
 }
 ~AdapterApplication()
 {
  if(this->m_lpTarget)
  {
   delete this->m_lpTarget;
  }
  cout<<"call ~AdapterApplication"<<endl;
 }

 int Request(const string& strName)
 {
  if(!this->m_lpTarget)
  {
  this->m_lpTarget=new Adapter(); //原来的类
  }
  if(!this->m_lpTarget)
  {
  return -1;
  }
  return this->m_lpTarget->Request(strName);//用户自定义的类
 }
}

#endif

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值