适配器模式(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

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

AdvanceMediaPlayer.h

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

步骤 2

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

Mp4Player.h及事实上现

#pragma once
#include "advancemediaplayer.h"
class Mp4Player :
public AdvanceMediaPlayer
{
public:
Mp4Player(void);
~Mp4Player(void);
virtual void playVcl(string& filename);
virtual void playMp4(string& filename);
}; void Mp4Player::playVcl(string& filename){
//null
}
void Mp4Player::playMp4(string& filename){
cout <<"playing mp4 media file.name"<< filename << endl;
}

VclPlayer.h及实现

#pragma once
#include "advancemediaplayer.h"
class VclPlayer :
public AdvanceMediaPlayer
{
public:
VclPlayer(void);
~VclPlayer(void);
virtual void playVcl(string& filename);
virtual void playMp4(string& filename);
};
void VclPlayer::playVcl(string& filename){
cout <<"playing vcl media file.name"<< filename << endl;
}
void VclPlayer::playMp4(string& filename){
//null
}

步骤 3

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

AdapterMediaPlayer.h和AdapterMediaPlayer.cpp

#pragma once
#include "mediaplayer.h"
#include "AdvanceMediaPlayer.h"
class AdapterMediaPlayer :
public MediaPlayer
{
public:
AdapterMediaPlayer(string& audioType);
~AdapterMediaPlayer(void);
virtual void play(string& audioType, string& filename);
private:
AdvanceMediaPlayer* advanceMusicPlayer;
}; #include "StdAfx.h"
#include "AdapterMediaPlayer.h"
#include "Mp4Player.h"
#include "VclPlayer.h"
AdapterMediaPlayer::AdapterMediaPlayer(string& audioType)
{
if (audioType.compare("vcl") == 0)
{
this->advanceMusicPlayer = new VclPlayer();
}else if (audioType.compare("mp4") == 0)
{
this->advanceMusicPlayer = new Mp4Player();
}
} AdapterMediaPlayer::~AdapterMediaPlayer(void)
{
if (advanceMusicPlayer != NULL)
{
delete advanceMusicPlayer;
advanceMusicPlayer = NULL;
}
} void AdapterMediaPlayer::play(string& audioType, string& filename)
{
if (audioType.compare("vcl") == 0)
{
this->advanceMusicPlayer->playVcl(filename);
}else if (audioType.compare("mp4") == 0)
{
this->advanceMusicPlayer->playMp4(filename);
}
}

步骤 4

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

AudioPlayer.h和AudioPlayer.cpp

#pragma once
#include "mediaplayer.h"
#include "AdapterMediaPlayer.h"
class AudioPlayer :
public MediaPlayer
{
public:
AudioPlayer(void);
~AudioPlayer(void);
void play(string& audioType, string& filename);
private:
AdapterMediaPlayer* mediaAdapter;
}; #include "StdAfx.h"
#include "AudioPlayer.h" AudioPlayer::AudioPlayer(void)
{
mediaAdapter = NULL;
} AudioPlayer::~AudioPlayer(void)
{
if (mediaAdapter != NULL)
{
delete mediaAdapter ;
mediaAdapter =NULL;
}
} void AudioPlayer::play(string& audioType, string& filename)
{
if (audioType.compare("mp3") == 0)
{
cout << "playing mp3 file.name:" << filename << endl;
}else if (!audioType.compare("vcl") || !audioType.compare("mp4"))
{//这里easy出现了内存泄露。
mediaAdapter = new AdapterMediaPlayer(audioType);
mediaAdapter->play(audioType,filename); }else{
cout << "Invalid media." << audioType << "and this format not support." << endl;
} if (mediaAdapter != NULL)
{
delete mediaAdapter ;
mediaAdapter =NULL;
}//指针释放原则,构造new析构delete,函数中new函数中delete,最后析构还有保险delete。
}

步骤 5

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

#include "stdafx.h"
#include "AudioPlayer.h" int _tmain(int argc, _TCHAR* argv[])
{
AudioPlayer* audioPlayer = new AudioPlayer();
audioPlayer->play(string("mp3"), string("beyond the horizon.mp3"));
audioPlayer->play(string("mp4"), string("alone.mp4"));
audioPlayer->play(string("vcl"), string("far far away.vcl"));
audioPlayer->play(string("avi"), string("mind me.avi"));
delete audioPlayer;
audioPlayer = NULL;
system("pause");
return 0;
}

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

设计模式之适配器模式(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. CSS之BFC、IFC、FFC and GFC

    CSS之BFC.IFC.FFC and GFC 什么是FC? BFC(Block Formatting Contexts) BFC的布局规则: 如何生成BFC: IFC(Inline Formatti ...

  2. RocketMQ的部署方式及持久化方式

    RocketMQ 的 Broker 有三种集群部署方式: 1. 单台 Master 部署: 2. 多台 Master部署: 3. 多 Master 多 Slave 部署:采用第 3 种部署方式时, M ...

  3. Class.forName(String name)方法,到底会触发那个类加载器进行类加载行为?

    4.2 在代码中直接调用Class.forName(String name)方法,到底会触发那个类加载器进行类加载行为? Class.forName(String name)默认会使用调用类的类加载器 ...

  4. spring mvc Controller中使用@Value无法获取属性值

    在使用spring mvc时,实际上是两个spring容器: 1,dispatcher-servlet.xml 是一个,我们的controller就在这里,所以这个里面也需要注入属性文件 org.sp ...

  5. jsp中生成txt文件

    import jxl.Workbook; import jxl.write.Label; import jxl.write.WritableSheet; import jxl.write.Writab ...

  6. C#中的托管与非托管

    在.net 编程环境中,系统的资源分为托管资源和非托管资源. 字面理解托管,就是托付个别人管理,要的是结果,具体怎么完成的我并不关心,就像某些'牛逼'的老板“我只要结果”那样. 在.NET FRAME ...

  7. select case when if 的一些用法

    概述:sql语句中的case语句与高级语言中的switch语句,是标准sql的语法,适用于一个条件判断有多种值的情况下分别执行不同的操作. 首先,让我们看一下CASE的语法.在一般的SELECT中,其 ...

  8. Python并发编程-Redis

    Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Remote Dictionary Server(Redis)是一个基于 key-value ...

  9. ElementUI的提示框的使用记录

    1.popover点击之后隐藏 问题描述:做了一个通知面板功能,下面提示信息有路由,每次点击消息呢,就跳转到了路由页面,但是此时这个面板没关闭,希望将其关闭 解决:官方文档有个属性 <div&g ...

  10. web 实时通信的方法总结

    1.Web端即时通讯技术 即时通讯技术简单的说就是实现这样一种功能:服务器端可以即时地将数据的更新或变化反应到客户端,例如消息即时推送等功能都是通过这种技术实现的. 但是在Web中,由于浏览器的限制, ...