作者:billy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
适配器模式
适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。
这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。
使用场景
- 系统需要使用现有的类,而这些类的接口不符合系统的需要。
- 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
- 需要一个统一的输出接口,而输入端的类型不可预知。
优缺点
-
优点:
1、可以让任何两个没有关联的类一起运行。
2、提高了类的复用。
3、增加了类的透明度。
4、灵活性好。 -
缺点:
过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。
注意事项
适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。
UML结构图
代码实现
first_interface.h
创建抽象类 - 多媒体播放器; 创建具体类 - vlc播放器、mp4播放器
#include <string>
#include <iostream>
using namespace std;
class AdvancedMediaPlayer //基类-多媒体播放器
{
public:
AdvancedMediaPlayer() {}
virtual ~AdvancedMediaPlayer() {}
virtual void playVlc(string fileName) = 0;
virtual void playMp4(string fileName) = 0;
};
class VlcPlayer: public AdvancedMediaPlayer //子类-vlc播放器
{
public:
void playVlc(string fileName)
{
cout << "Playing vlc file. Name: " + fileName << endl;
}
void playMp4(string fileName)
{
cout << fileName + " do nothing" << endl;
}
};
class Mp4Player: public AdvancedMediaPlayer //子类-mp4播放器
{
public:
void playVlc(string fileName)
{
cout << fileName + " do nothing" << endl;
}
void playMp4(string fileName)
{
cout << "Playing mp4 file. Name: " + fileName << endl;
}
};
second_interface.h
原来的AudioPlayer只能播放mp3格式的文件,通过适配器MediaAdapter就可以播放vlc和mp4格式的文件了
#include "first_interface.h"
class MediaPlayer //基类-音乐播放器
{
public:
MediaPlayer() {}
virtual ~MediaPlayer() {}
virtual void play(string audioType, string fileName) = 0;
};
class MediaAdapter: public MediaPlayer
{
public:
MediaAdapter(string audioType)
{
if (audioType == "vlc")
{
player = new VlcPlayer();
}
else if(audioType == "mp4")
{
player = new Mp4Player();
}
else
{
player = nullptr;
}
}
void play(string audioType, string fileName)
{
if (audioType == "vlc")
{
player->playVlc(fileName);
}
else if(audioType == "mp4")
{
player->playMp4(fileName);
}
}
public:
AdvancedMediaPlayer *player;
};
//默认 AudioPlayer 可以播放 mp3 格式的音频文件,通过适配器类 MediaAdapter 来播放 vlc 和 mp4 格式的文件
class AudioPlayer: public MediaPlayer
{
public:
void play(string audioType, string fileName)
{
if (audioType == "mp3")
{
cout << "Playing mp3 file. Name: " + fileName << endl;
}
else if(audioType == "mp4" || audioType == "vlc")
{
MediaAdapter * adapter = new MediaAdapter(audioType);
adapter->play(audioType, fileName);
}
else
{
cout << "Invalid media. " + audioType + " format not supported";
}
}
};
main.cpp
实例应用 - 使用播放器播放各种格式的文件
#include "second_interface.h"
int main()
{
AudioPlayer *audioPlayer = new AudioPlayer();
audioPlayer->play("mp3", "beyond the horizon.mp3");
audioPlayer->play("mp4", "alone.mp4");
audioPlayer->play("vlc", "far far away.vlc");
audioPlayer->play("avi", "mind me.avi");
return 0;
}
运行结果:
Playing mp3 file. Name: beyond the horizon.mp3
Playing mp4 file. Name: alone.mp4
Playing vlc file. Name: far far away.vlc
Invalid media. avi format not supported