适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这样的类型的设计模式属于结构型模式。它结合了两个独立接口的功能。

意图:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本因为接口不兼容而不能一起工作的那些类能够一起工作。

主要解决:主要解决在软件系统中。经常要将一些"现存的对象"放到新的环境中,而新环境要求的接口是现对象不能满足的。

何时使用: 1、系统须要使用现有的类,而此类的接口不符合系统的须要。 2、想要建立一个能够反复使用的类,用于与一些彼此之间没有太大关联的一些类,包含一些可能在将来引进的类一起工作,这些源类不一定有一致的接口。 3、通过接口转换。将一个类插入还有一个类系中。(比方老虎和飞禽,如今多了一个飞虎。在不添加实体的需求下,添加一个适配器,在里面包容一个虎对象,实现飞的接口。

怎样解决:继承或依赖(推荐)。

长处: 1、能够让不论什么两个没有关联的类一起执行。 2、提高了类的复用。 3、添加了类的透明度。 4、灵活性好。

缺点: 1、过多地使用适配器,会让系统非常零乱,不易总体进行把握。比方,明明看到调用的是 A 接口,事实上内部被适配成了 B 接口的实现,一个系统假设太多出现这样的情况,无异于一场灾难。因此假设不是非常有必要,能够不使用适配器。而是直接对系统进行重构。 2.因为 JAVA 至多继承一个类。所以至多仅仅能适配一个适配者类,并且目标类必须是抽象类。

使用场景:有动机地改动一个正常执行的系统的接口,这时应该考虑使用适配器模式。

注意事项:适配器不是在具体设计时加入的。而是解决正在服役的项目的问题。

实现:

我们有一个 MediaPlayer 接口和一个实现了 MediaPlayer 接口的实体类 AudioPlayer。默认情况下。AudioPlayer 能够播放 mp3 格式的音频文件。

我们还有还有一个接口 AdvancedMediaPlayer 和实现了 AdvancedMediaPlayer 接口的实体类。该类能够播放 vlc 和 mp4 格式的文件。

我们想要让 AudioPlayer 播放其它格式的音频文件。为了实现这个功能,我们须要创建一个实现了 MediaPlayer 接口的适配器类MediaAdapter,并使用 AdvancedMediaPlayer 对象来播放所需的格式。

AudioPlayer 使用适配器类 MediaAdapter 传递所需的音频类型,不须要知道能播放所需格式音频的实际类。

代码:

步骤 1

为媒体播放器和更高级的媒体播放器创建接口。

MediaPlayer.h

  1. #pragma once
  2. /*MediaPlayer.h*/
  3. #include "stdafx.h"
  4. class MediaPlayer{
  5. public:
  6. virtual void play(string& audioType, string& filename) = 0;
  7. virtual ~MediaPlayer(){cout<< "this is mediaplayer desconstructor." << endl;}
  8. };

AdvanceMediaPlayer.h

  1. #pragma once
  2. /*AdvanceMediaPlayer.h*/
  3. #include "stdafx.h"
  4. class AdvanceMediaPlayer{
  5. public:
  6. //这里构造要么不写。要么就写为内联空实现的形式AdvanceMediaPlayer(){}
  7. //AdvanceMediaPlayer();
  8. virtual ~AdvanceMediaPlayer(){}
  9. virtual void playVcl(string& filename) = 0;
  10. virtual void playMp4(string& filename) = 0;
  11. };

步骤 2

创建实现了 AdvancedMediaPlayer 接口的实体类。

Mp4Player.h及事实上现

  1. #pragma once
  2. #include "advancemediaplayer.h"
  3. class Mp4Player :
  4. public AdvanceMediaPlayer
  5. {
  6. public:
  7. Mp4Player(void);
  8. ~Mp4Player(void);
  9. virtual void playVcl(string& filename);
  10. virtual void playMp4(string& filename);
  11. };
  12.  
  13. void Mp4Player::playVcl(string& filename){
  14. //null
  15. }
  16. void Mp4Player::playMp4(string& filename){
  17. cout <<"playing mp4 media file.name"<< filename << endl;
  18. }

VclPlayer.h及实现

  1. #pragma once
  2. #include "advancemediaplayer.h"
  3. class VclPlayer :
  4. public AdvanceMediaPlayer
  5. {
  6. public:
  7. VclPlayer(void);
  8. ~VclPlayer(void);
  9. virtual void playVcl(string& filename);
  10. virtual void playMp4(string& filename);
  11. };
  12. void VclPlayer::playVcl(string& filename){
  13. cout <<"playing vcl media file.name"<< filename << endl;
  14. }
  15. void VclPlayer::playMp4(string& filename){
  16. //null
  17. }

步骤 3

创建实现了 MediaPlayer 接口的适配器类。

AdapterMediaPlayer.h和AdapterMediaPlayer.cpp

  1. #pragma once
  2. #include "mediaplayer.h"
  3. #include "AdvanceMediaPlayer.h"
  4. class AdapterMediaPlayer :
  5. public MediaPlayer
  6. {
  7. public:
  8. AdapterMediaPlayer(string& audioType);
  9. ~AdapterMediaPlayer(void);
  10. virtual void play(string& audioType, string& filename);
  11. private:
  12. AdvanceMediaPlayer* advanceMusicPlayer;
  13. };
  14.  
  15. #include "StdAfx.h"
  16. #include "AdapterMediaPlayer.h"
  17. #include "Mp4Player.h"
  18. #include "VclPlayer.h"
  19. AdapterMediaPlayer::AdapterMediaPlayer(string& audioType)
  20. {
  21. if (audioType.compare("vcl") == 0)
  22. {
  23. this->advanceMusicPlayer = new VclPlayer();
  24. }else if (audioType.compare("mp4") == 0)
  25. {
  26. this->advanceMusicPlayer = new Mp4Player();
  27. }
  28. }
  29.  
  30. AdapterMediaPlayer::~AdapterMediaPlayer(void)
  31. {
  32. if (advanceMusicPlayer != NULL)
  33. {
  34. delete advanceMusicPlayer;
  35. advanceMusicPlayer = NULL;
  36. }
  37. }
  38.  
  39. void AdapterMediaPlayer::play(string& audioType, string& filename)
  40. {
  41. if (audioType.compare("vcl") == 0)
  42. {
  43. this->advanceMusicPlayer->playVcl(filename);
  44. }else if (audioType.compare("mp4") == 0)
  45. {
  46. this->advanceMusicPlayer->playMp4(filename);
  47. }
  48. }

步骤 4

创建实现了 MediaPlayer 接口的实体类。

AudioPlayer.h和AudioPlayer.cpp

  1. #pragma once
  2. #include "mediaplayer.h"
  3. #include "AdapterMediaPlayer.h"
  4. class AudioPlayer :
  5. public MediaPlayer
  6. {
  7. public:
  8. AudioPlayer(void);
  9. ~AudioPlayer(void);
  10. void play(string& audioType, string& filename);
  11. private:
  12. AdapterMediaPlayer* mediaAdapter;
  13. };
  14.  
  15. #include "StdAfx.h"
  16. #include "AudioPlayer.h"
  17.  
  18. AudioPlayer::AudioPlayer(void)
  19. {
  20. mediaAdapter = NULL;
  21. }
  22.  
  23. AudioPlayer::~AudioPlayer(void)
  24. {
  25. if (mediaAdapter != NULL)
  26. {
  27. delete mediaAdapter ;
  28. mediaAdapter =NULL;
  29. }
  30. }
  31.  
  32. void AudioPlayer::play(string& audioType, string& filename)
  33. {
  34. if (audioType.compare("mp3") == 0)
  35. {
  36. cout << "playing mp3 file.name:" << filename << endl;
  37. }else if (!audioType.compare("vcl") || !audioType.compare("mp4"))
  38. {//这里easy出现了内存泄露。
  39. mediaAdapter = new AdapterMediaPlayer(audioType);
  40. mediaAdapter->play(audioType,filename);
  41.  
  42. }else{
  43. cout << "Invalid media." << audioType << "and this format not support." << endl;
  44. }
  45.  
  46. if (mediaAdapter != NULL)
  47. {
  48. delete mediaAdapter ;
  49. mediaAdapter =NULL;
  50. }//指针释放原则,构造new析构delete,函数中new函数中delete,最后析构还有保险delete。
  51. }

步骤 5

使用 AudioPlayer 来播放不同类型的音频格式。

  1. #include "stdafx.h"
  2. #include "AudioPlayer.h"
  3.  
  4. int _tmain(int argc, _TCHAR* argv[])
  5. {
  6. AudioPlayer* audioPlayer = new AudioPlayer();
  7. audioPlayer->play(string("mp3"), string("beyond the horizon.mp3"));
  8. audioPlayer->play(string("mp4"), string("alone.mp4"));
  9. audioPlayer->play(string("vcl"), string("far far away.vcl"));
  10. audioPlayer->play(string("avi"), string("mind me.avi"));
  11. delete audioPlayer;
  12. audioPlayer = NULL;
  13. system("pause");
  14. return 0;
  15. }

最后。代码仅仅是參考,最重要的还是思想。

设计模式之适配器模式(Adapter Pattern)C++实现的更多相关文章

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

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

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

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

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

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

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

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

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

    Adapter Pattern的作用是在不改变功能的前提下转换接口.Adapter分为两类,一类是Object Adapter, 还有一类是Class Adapter.因为Class Adapter的 ...

  6. 夜话JAVA设计模式之适配器模式(adapter pattern)

    适配器模式:将一个类的接口,转换成客户期望的另一个接口,让不兼容的接口变成兼容. 1.类适配器模式:通过多重继承来实现适配器功能.多重继承就是先继承要转换的实现类,再实现被转换的接口. 2.对象适配器 ...

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

    概述 描述 将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper). 套路 Target(目标抽象类) 目标抽象类定义了客户所需要的接口,可 ...

  8. 设计模式系列之适配器模式(Adapter Pattern)——不兼容结构的协调

    模式概述 模式定义 模式结构图 模式伪代码 类适配器,双向适配器,缺省适配器 类适配器 双向适配器 缺省适配器 模式应用 模式在JDK中的应用 模式在开源项目中的应用 模式总结 主要优点 主要缺点 适 ...

  9. 设计模式 - 适配器模式(adapter pattern) 具体解释

    适配器模式(adapter pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 适配器模式(adapter pattern): 将一个类的接 ...

  10. 设计模式 - 适配器模式(adapter pattern) 枚举器和迭代器 具体解释

    适配器模式(adapter pattern) 枚举器和迭代器 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考适配器模式(adapter patter ...

随机推荐

  1. Node.js modules you should know about: request

    Hey everyone! This is the fourth post in my new node.js modules you should know about article series ...

  2. hdu1238 Substrings (暴力)

    http://acm.hdu.edu.cn/showproblem.php?pid=1238 Substrings Time Limit : 2000/1000ms (Java/Other)   Me ...

  3. Xsolla和Crytek合作,对游戏战争前线推出全新支付方式

    新闻稿: Sherman Oaks, 加州 (美国) –2014年 10月 15日-计费提供商Xsolla今日正式宣布.和著名游戏开发商以及发行商 Crytek.这次合作意味着玩家能够期待大量的游戏内 ...

  4. java基础之hashcode理解及hashmap实现原理及MD5

    HashCode值 1. hashcode值是int的,64位.int hashCode(). 2. java object类默认的hashcode()计算方法是根据对象的内存地址来计算的.所以可由此 ...

  5. arcgis python 沿线生成点

    # coding: utf-8 """ Source Name: generatepointsfromlines.py Version: ArcGIS 10.4/Pro ...

  6. iOS 下 Podfile 使用方法

    配置 Podlist Pod 是 iOS 下包管理工具,类似于 JavaScript 里的 npm 或 yarn. 创建 Podfile 创建 Podfile 有两种方式: 打开 Terminal,在 ...

  7. 解决sdk manager下载非常慢或者下载失败

    有了sdk manager,打开它,想下载一些须要的东西总是会发现非常慢,然后就仅仅好慢慢等待,等待许久之后最后是失败了,这样就会非常麻烦,以下我总结总结,怎样解决这些问题,让你在分分钟下载好这些东西 ...

  8. .NET:CLR via C# Exceptions and State Management

    重点学习的个概念 unhandled exceptions constrained execution regions code contracts runtime wrapped exception ...

  9. Git 学习(四)操作修改和版本穿梭

    Git 学习(四)操作修改和版本穿梭 之前的章节,已介绍了本地Git库创建.暂存区增.删.改,以及提交版本库:可回顾下命令操作: git add 和 git commit. 光有之前章节的操作,Git ...

  10. 第十七章 springboot + devtools(热部署)

    技术介绍 devtools:是boot的一个热部署工具,当我们修改了classpath下的文件(包括类文件.属性文件.页面等)时,会重新启动应用(由于其采用的双类加载器机制,这个启动会非常快,如果发现 ...