适配器模式(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;
}
最后。代码仅仅是參考,最重要的还是思想。