1、问题背景

Adapter模式解决的问题在生活中经常会遇到:比如我们有一个Team为外界提供S类服务,但是我们Team里面没有能够完成此项任务的member,然后我们得知有A可以完成这项服务(这项任务提供的服务重新取了个名字叫S’,并且他不对外公布他的具体实现)。为了保证我们对外的服务类别的一致性(提供S服务),我们有以下两种方式解决这个问题:

1)把A君直接招安到我们Team为我们工作,提供S服务的时候让A君去办就是了;

2)A君可能在别的地方有工作,并且不准备接受我们的招安,于是我们Team可以想这样一种方式解决问题:我们安排B君去完成这项任务,并做好工作(Money)让B君工作的时候可以向A君请教,因此B君就是一个复合体(提供S服务,但是是A君的继承弟子)。

实际上在软件系统设计和开发中,这种问题也会经常遇到:我们为了完成某项工作购买了一个第三方的库来加快开发。这就带来了一个问题:我们在应用程序中已经设计好了接口,与这个第三方提供的接口不一致,为了使得这些接口不兼容的类(不能在一起工作)可以在一起工作了,Adapter模式提供了将一个类(第三方库)的接口转化为客户(购买使用者)希望的接口。

在上面生活中问题的解决方式也就正好对应了Adapter模式的两种类别:类模式和对象模式。

2、模式示意图

图1、类的适配器模式示意图

图2、对象的适配器模式示意图

3、代码实现

3.1、Adapter(Class)

代码实现如下:

//

//Adapter.h

//

#ifndef _ADAPTER_H_

#define _ADAPTER_H_

#include

using namespace std;

class Target

{

public:

Target();

virtual ~Target();

virtual void fnRequest();

protected:

private:

};

class Adaptee

{

public:

Adaptee();

~Adaptee();

void fnSpecificRequest();

protected:

private:

};

class Adapter:public Target,private Adaptee

{

public:

Adapter();

~Adapter();

void fnRequest();

protected:

private:

};

#endif //#ifndef _ADAPTER_H_

//

//Adapter.cpp

//

#include "Adapter.h"

Target::Target()

{

}

Target::~Target()

{

}

void Target::fnRequest()

{

cout<

}

Adaptee::Adaptee()

{

}

Adaptee::~Adaptee()

{

}

void Adaptee::fnSpecificRequest()

{

cout<

}

Adapter::Adapter()

{

}

Adapter::~Adapter()

{

}

void Adapter::fnRequest()

{

this->fnSpecificRequest();

}

//

//main.cpp

//

#include "Adapter.h"

void main()

{

Target * pTarget = NULL;

pTarget = new Adapter();

pTarget->fnRequest();

delete pTarget;

pTarget = NULL;

}

运行结果如下:

3.2、Adapter(Object)

代码实现如下:

//

//Adapter.h

//

#ifndef _ADAPTER_H_

#define _ADAPTER_H_

#include

using namespace std;

class Target

{

public:

Target();

virtual ~Target();

virtual void fnRequest();

protected:

private:

};

class Adaptee

{

public:

Adaptee();

~Adaptee();

void fnSpecificRequest();

protected:

private:

};

class Adapter:public Target

{

public:

Adapter(Adaptee* ade);

~Adapter();

void fnRequest();

protected:

private:

Adaptee* _ade;

};

#endif //#ifndef _ADAPTER_H_

//

//Adapter.cpp

//

#include "Adapter.h"

Target::Target()

{

}

Target::~Target()

{

}

void Target::fnRequest()

{

cout<

}

Adaptee::Adaptee()

{

}

Adaptee::~Adaptee()

{

}

void Adaptee::fnSpecificRequest()

{

cout<

}

Adapter::Adapter(Adaptee* ade)

{

_ade = ade;

}

Adapter::~Adapter()

{

delete _ade;

_ade = NULL;

}

void Adapter::fnRequest()

{

_ade->fnSpecificRequest();

}

//

//main.cpp

//

#include "Adapter.h"

void main()

{

Target * pTarget = NULL;

pTarget = new Adapter(new Adaptee);

pTarget->fnRequest();

delete pTarget;

pTarget = NULL;

}

运行结果如下:

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

4、总结与讨论

在Adapter模式的两种模式中,有一个很重要的概念就是接口继承和实现继承的区别和联系。接口继承和实现继承是面向对象领域的两个重要的概念,接口继承指的是通过继承,子类获得了父类的接口,而实现继承指的是通过继承子类获得了父类的实现(并不统一共同接口)。在C++中的public继承既是接口继承又是实现继承,因为子类在继承了父类后既可以对外提供父类中的接口操作,又可以获得父类的接口实现。当然我们可以通过一定的方式和技术模拟单独的接口继承和实现继承,例如我们可以通过private继承获得实现继承的效果,通过纯抽象基类模拟接口继承的效果,在其他语言中可以用 interface来获得专门的接口继承。

adapter为null_软件设计精要之——适配器(Adapter)模式相关推荐

  1. 《软件设计精要与模式》前言

    缘起 用过去几年互联网上最酷,而在当下已经被用滥的名词来说,我在2004年成为了一名博客,用日志的方式记录自己成长的经历.坦白说,技术的成长远远比身体的发育更加地艰辛与缓慢,尤其是当今信息爆炸的年代, ...

  2. 教你如何阅读本书,如何学好软件设计——软件设计精要与模式前言

    前    言 缘起 用过去几年互联网上最酷,而在当下已经被用滥的名词来说,我在2004年成为了一名博客,用日志的方式记录自己成长的经历.坦白说,技术的成长远远比身体的发育更加地艰辛与缓慢,尤其是当今信 ...

  3. 《软件设计精要与模式》第二版源代码

    <软件设计精要与模式>第二版的代码相较于第一版而言,做了一定的修改.代码采用C#语言编写,并在Windows XP, Visual Studio 2008, SQL Server 2005 ...

  4. 踏上《软件设计精要与模式》第二版的征途

    距离<软件设计精要与模式>的出版已有两年多的时间,从出版之初的热销到后来归于平淡,我也经历了从兴奋期到蛰伏期的过程.这本书的反应不算好,也不算坏.在浩瀚如大海一般的书市里,就好似一滴水珠融 ...

  5. 《软件设计精要与模式》推荐序三

    微软MVP InfoQ中文站.NET社区首席编辑 朱永光 很早就在博客园上拜读过张逸的文章,尤其对他在设计模式方面的经验和见解印象深刻.在我把他邀请进InfoQ中文站编辑团队后,经过深入而频繁的交流, ...

  6. [书籍推荐]《软件设计精要与模式(第2版)》-张逸——提高设计模式及软件设计的方法...

    <软件设计精要与模式(第2版)>是园子里张逸大大今年4月出版的关于软件设计及设计模式方面的书,我是5月下旬到手,每天晚上看一章,断断续续的到昨天晚上总算把全书28章看完了,感受很深,以往在 ...

  7. 《软件设计精要与模式》

    "给我一个支点,我就能撬起地球".关键不在于力量有多大,而在于如何合理地利用力量.软件设计同样如此.思想的确立,技巧的把握,将在很大程度上决定软 件架构的合理性.基于这样的目的,本 ...

  8. 软件设计精要与模式 张逸

    一.设计之道 软件设计两种方法:计划的设计(满足扩展的设计)和演进的设计(极限) 软件架构设计: 1.程序组织(Program ) 需求--系统的功能模块(或子系统)--封装成包(考虑解耦--面向接口 ...

  9. 《软件设计精要与模式》之Factory Method模式

          声明:我发布本章节主要是和大家分享这本书里的知识点,如果涉及到了侵权请作者或是相关人士留言,我会删除.       Factory Method模式是应用最为广泛的设计模式,毕竟他负责了一 ...

最新文章

  1. css案例学习之div ul li a 实现导航效果
  2. ios开发笔记之 APNS推送服务的实现
  3. python sns绘制回归线_SVM--支持向量机amp;Python代码
  4. boost::math模块使用二项分布复制 NAG 库调用的测试程序
  5. pixhawk篇之坐标系转化,相关转化矩阵知识,算法截取
  6. JVM 性能调优监控工具 jps、jstack、jmap、jhat、jstat、hprof 使用详解
  7. 面试经验分享|精华版
  8. CentOS+Nginx一步一步开始配置负载均衡
  9. 穷人为什么会越穷,穷的时候以下三个事情不能干
  10. 一个小例子介绍Obj-C的函数命名方式
  11. 苹果无人车裁员200人,收购特斯拉呼声再起
  12. Android 开机优化
  13. java 读取资源文件最详细解读
  14. 【unprofessional use Blog003】基因数据库NCBI相关介绍
  15. 方正璞华:硬核攻关,自主创新,推动印前处理自动化云流程走向世界
  16. 泡泡网 前有古人后有来者! 胶水处理器回顾
  17. android没有adm_Android--Android Studio 打开ADM报错
  18. 云计算对传统软件工程的影响
  19. 连线9宫格可实现手势密码等
  20. oracle日期函数,转换函数

热门文章

  1. spring 循环依赖_简单说说 Spring 的循环依赖
  2. MySQL事务隔离级别的实现原理
  3. 【最新合集】PAT乙级最优题解(题解+解析+代码)
  4. 1092 最好吃的月饼 (20分)_24行代码AC
  5. 9行代码AC——HDU 6857 -Clockwise or Counterclockwise(2020 Multi-University Training Contest 8)(判断三点顺序)
  6. html flash 循环播放,在网页中插入flv格式的flash视频怎么让其循环播放_html/css_WEB-ITnose...
  7. flutter 动画json_Flutter 50: 图解动画小插曲之 Lottie 动画
  8. 利用Java实现串口全双工通讯
  9. iphone文件访问ftp服务器,将文件上传到iPhone上的FTP服务器
  10. 太原学计算机的职高,山西太原职高学校排名