在 Adapter 模式的结构图中可以看到,类模式的 Adapter 采用继承的方式复用 Adaptee
的接口,而在对象模式的 Adapter 中我们则采用组合的方式实现 Adaptee 的复用

类模式的adapter

#include<iostream>

using namespace std;

class Target
{
public:
Target();
virtual ~Target();
virtual void Request();
protected:
private:
};
class Adaptee
{
public:
Adaptee();
~Adaptee();
void SpecificRequest();
protected:
private:
};
class Adapter:public Target,private Adaptee
{
public:
Adapter();
~Adapter();
void Request();
protected:
private:
}; Target::Target()
{
}
Target::~Target()
{
}
void Target::Request()
{
std::cout<<"Target::Request"<<std::endl;
}
Adaptee::Adaptee()
{ } Adaptee::~Adaptee()
{
}
void Adaptee::SpecificRequest()
{
std::cout<<"Adaptee::SpecificRequest"<<
std::endl;
}
Adapter::Adapter()
{
}
Adapter::~Adapter()
{
}
void Adapter::Request()
{
this->SpecificRequest();
} int main(int argc,char* argv[])
{
Target * adt = new Adapter(); adt->Request(); return ;
}

对象模式的 Adapter

#include<iostream>

using namespace std;

class Target
{
public:
Target();
virtual ~Target();
virtual void Request();
protected:
private:
};
class Adaptee
{
public:
Adaptee();
~Adaptee();
void SpecificRequest();
protected:
private:
};
class Adapter:public Target
{
public:
Adapter(Adaptee* ade);
~Adapter();
void Request();
protected:
private:
Adaptee* _ade;
};
Target::Target()
{
}
Target::~Target()
{
}
void Target::Request()
{
std::cout<<"Target::Request"<<std::endl;
}
Adaptee::Adaptee()
{
}
Adaptee::~Adaptee()
{
}
void Adaptee::SpecificRequest()
{
std::cout<<"Adaptee::SpecificRequest"<<
std::endl;
}
Adapter::Adapter(Adaptee* ade)
{
this->_ade = ade;
}
Adapter::~Adapter()
{
}
void Adapter::Request()
{
_ade->SpecificRequest();
} int main(int argc,char* argv[])
{
Adaptee* ade = new Adaptee; Target* adt = new Adapter(ade); adt->Request(); return ;
}

说明
Adapter 模式实现上比较简单,要说明的是在类模式 Adapter 中,我们通过 private 继承Adaptee 获得实现继承的效果,而通过 public 继承 Target 获得接口继承的效果(有关实现继承和接口继承参见讨论部分)。
„ 讨论
在 Adapter 模式的两种模式中,有一个很重要的概念就是接口继承和实现继承的区别和联系。接口继承和实现继承是面向对象领域的两个重要的概念,接口继承指的是通过继承,子类获得了父类的接口,而实现继承指的是通过继承子类获得了父类的实现(并不统共接口)。在 C++中的 public 继承既是接口继承又是实现继承,因为子类在继承了父类后既可以对外提供父类中的接口操作,又可以获得父类的接口实现。当然我们可以通过一定的方式和技术模拟单独的接口继承和实现继承,例如我们可以通过 private 继承获得实现继承的效果(private 继承后,父类中的接口都变为 private,当然只能是实现继承了。),通过纯抽象基类模拟接口继承的效果,但是在 C++中 pure virtual function 也可以提供默认实现,因此这是不纯正的接口继承,但是在 Java 中我们可以 interface 来获得真正的接口继承了。

一个对象模Adpater的例子:

DP上的定义:适配器模式将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。它包括类适配器和对象适配器,本文针对的是对象适配器。举个例子,在STL中就用到了适配器模式。STL实现了一种数据结构,称为双端队列(deque),支持前后两段的插入与删除。STL实现栈和队列时,没有从头开始定义它们,而是直接使用双端队列实现的。这里双端队列就扮演了适配器的角色。队列用到了它的后端插入,前端删除。而栈用到了它的后端插入,后端删除。假设栈和队列都是一种顺序容器,有两种操作:压入和弹出。下面给出相应的UML图,与DP上的图差不多。

根据上面的UML图,很容易给出实现。

//双端队列
class Deque
{
public:
void push_back(int x) { cout<<"Deque push_back"<<endl; }
void push_front(int x) { cout<<"Deque push_front"<<endl; }
void pop_back() { cout<<"Deque pop_back"<<endl; }
void pop_front() { cout<<"Deque pop_front"<<endl; }
};
//顺序容器
class Sequence
{
public:
virtual void push(int x) = ;
virtual void pop() = ;
};
//栈
class Stack: public Sequence
{
public:
void push(int x) { deque.push_back(x); }
void pop() { deque.pop_back(); }
private:
Deque deque; //双端队列
};
//队列
class Queue: public Sequence
{
public:
void push(int x) { deque.push_back(x); }
void pop() { deque.pop_front(); }
private:
Deque deque; //双端队列
};
int main()
{
Sequence *s1 = new Stack();
Sequence *s2 = new Queue();
s1->push(); s1->pop();
s2->push(); s2->pop();
delete s1; delete s2;
return ;
}

[设计模式] 7 适配器模式 adapter的更多相关文章

  1. 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern)

    原文:乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) 作者:webabc ...

  2. 8.3 GOF设计模式二: 适配器模式 Adapter

    GOF设计模式二: 适配器模式 Adapter  为中国市场生产的电器,到了美国,需要有一个转接器才能使用墙上的插座,这个转接 器的功能.原理?复习单实例模式  SingleTon的三个关键点  ...

  3. 怎样让孩子爱上设计模式 —— 7.适配器模式(Adapter Pattern)

    怎样让孩子爱上设计模式 -- 7.适配器模式(Adapter Pattern) 标签: 设计模式初涉 概念相关 定义: 适配器模式把一个类的接口变换成client所期待的还有一种接口,从而 使原本因接 ...

  4. 二十四种设计模式:适配器模式(Adapter Pattern)

    适配器模式(Adapter Pattern) 介绍将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作.示例有一个Message实体类 ...

  5. 【设计模式】适配器模式 Adapter Pattern

    适配器模式在软件开发界使用及其广泛,在工业界,现实中也是屡见不鲜.比如手机充电器,笔记本充电器,广播接收器,电视接收器等等.都是适配器. 适配器主要作用是让本来不兼容的两个事物兼容和谐的一起工作.比如 ...

  6. Java设计模式之适配器模式(Adapter)

    转载:<JAVA与模式>之适配器模式 这个总结的挺好的,为了加深印象,我自己再尝试总结一下 1.定义: 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法 ...

  7. JavaScript设计模式 Item9 --适配器模式Adapter

    适配器模式(转换器面模式),通常是为要使用的接口,不符本应用或本系统使用,而需引入的中间适配层类或对象的情况. 适配器模式的作用是解决两个软件实体间的接口不兼容的问题. 一.定义 适配器模式(Adap ...

  8. python 设计模式之适配器模式 Adapter Class/Object Pattern

    #写在前面 看完了<妙味>和<华医>,又情不自禁的找小说看,点开了推荐里面随机弹出的<暗恋.橘生淮南>,翻了下里面的评论,有个读者从里面摘了一段自己很喜欢的话出来, ...

  9. java设计模式之六适配器模式(Adapter)

    适配器模式将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题.主要分为三类:类的适配器模式.对象的适配器模式.接口的适配器模式.首先,我们来看看类的适配器模 ...

随机推荐

  1. JS学习第四课

    当我们删除某列表格,再添加新的一列时,它的序号该如何控制呢.这里id=oTab.tBodies[0].rows.length+1        otd.innerHTML=id++;   很关键哦. ...

  2. n盏灯亮灭问题

    前几天看了华为的一个上机操作题,讲得是n盏灯亮灭问题,本质上还是数学问题,感觉很有趣,和大家分享一下,问题描述如下: 有n盏灯排成一排,依次标号1,2,…,n,每盏灯都有一根拉线开关,最初电灯都是关着 ...

  3. 编译内核模块出现error: negative width in bit-field 错误

    今天在写一个简单的内核测试模块的时候出现了一个挺奇怪的问题,网上查了一下也没人解决,自己试了好久终于解决了,所以分享出来供大家参考,先贴出源码: /************************** ...

  4. ARM公布“物联网”嵌入式mbed OS系统软件平台

    继ARM公司发布了为嵌入式微控制器设计的Cortex-M7架构处理器,ARM又公布了专为廉价低功耗“物联网”设计的新版软件及系统平台,以加速物联网设备的发展及部署.该软件为基于ARM现有Cortex- ...

  5. JS重写alert,保证弹窗错误的友好性

    // ------------------------------------------------------------- // 重写alert,保证弹窗错误的友好性 var j_oldAler ...

  6. linux文件目录下各文件简介

    /bin:存放最常用命令: /boot:启动Linux的核心文件: /dev:设备文件: /etc:存放各种配置文件: /home:用户主目录: /lib:系统最基本的动态链接共享库: /mnt:一般 ...

  7. 11G RAC 简单命令

    1.查看集群状态: [root@rac1 ~]# su - grid [grid@rac1 ~]$ crsctl check clusterCRS-4537: Cluster Ready Servic ...

  8. Google面试题及答案

    1. 村子里有100对夫妻,其中每个丈夫都瞒着自己的妻子偷情...村里的每个妻子都能立即发现除自己丈夫之外的其他男人是否偷情,唯独不知道她自己的丈夫到底有没有偷情.村里的规矩不容忍通奸.任何一个妻子, ...

  9. VSC 使用Git进行版本控制

    Visual Studio Code 使用Git进行版本控制 请确保你安装了最新的VS Code.http://code.visualstudio.com/ 请确保安装了最新版的Git.https:/ ...

  10. 为什么V8引擎这么快?(转载)

    转载请注明出处:http://blog.csdn.net/horkychen Google研发的V8 JavaScript引擎性能优异.我们请熟悉内部程序实现的作者依源代码来看看V8是如何加速的. 作 ...