这是正确实施的适配器设计模式吗?如果不是,我错过了什么?
Is this an adapter design pattern correctly implemented? If not what am I missing?
我努力创建了一个适配器设计模式。一个简单的界面,用户可以使用它连接到旧的和现代的媒体播放器。
现代媒体播放器播放 mp4
格式,而旧播放器仅播放 wav
格式。使用 class mediaPlayerInterface 用户可以播放两种媒体类型。
如果您觉得这不是适配器设计模式,请评论缺少的内容。如何将其修改为适配器模式?我对设计模式有点陌生。
#include <iostream>
#include <string>
using namespace std;
class MediaPlayer
{
public:
virtual void playSong()=0;
};
class ModernMediaPlayer : public MediaPlayer
{
public:
void playSong( )
{
cout << "Playing from modern media player" << endl;
}
};
class oldMediaPlayer: public MediaPlayer
{
public:
void playSong( )
{
cout << "Playing from old media player" << endl;
}
};
class mediaPlayerInterface
{
private:
string fileType;
public:
mediaPlayerInterface(string fType)
{
fileType=fType;
}
MediaPlayer* getMediaPlayer( )
{
if (fileType == "mp4")
{
return new ModernMediaPlayer;
}
else if (fileType == "wav")
{
return new oldMediaPlayer;
}
}
};
int main()
{
mediaPlayerInterface *mIface = new mediaPlayerInterface("mp4");
MediaPlayer *mplayer = mIface->getMediaPlayer();
mplayer->playSong();
mIface = new mediaPlayerInterface("wav");
mplayer = mIface->getMediaPlayer();
mplayer->playSong();
}
Output:
Playing from modern media player
Playing from old media player
下面是一个适配器模式的例子。重要的是 AscSequenceControl 具有所有必需的功能,但它不能连接到 MovementPlanner,因为接口不兼容。所以RouteSegmenter确实是"adapts"这个。它具有正确的接口,其实现仅使用 AscSequenceControl。
因此在您的示例中:您有一个 MediaPlayer,其方法为:gotoTrack (int trackNr)。但是 class MediaPlayerUser 想说的是:mediaPlayer.nextTrack() 和 mediaPlayer.previousTrack()。所以你做了一个桥 class MediaPlayerBridge。它有一个属性 mediaPlayer 和调用 mediaPlayer.gotoTrack (++currentTrack) 的方法 nextTrack 和一个调用 mediaPlayer.gotoTrack (--currentTrack) 的方法 previousTrack。
嗯,适配器模式的基本思想是(我不懂C++,所以请原谅我的C#代码)--
你针对抽象进行编程
interface IPlayer
{
void Play();
void Stop();
void Shuffle();
}
class ModernPlayer : IPlayer
{
void Play() { // plays }
void Stop() { // stops }
void Shuffle() { // shuffles }
}
到目前为止一切顺利。你在你的代码中使用它,比如
IPlayer player = GetPlayer(); // some way to get an abstract IPlayer
player.Shuffle();
然后您意识到您需要一个不同的 IPlayer 实现。你找到一个有播放器的图书馆,但它有一套完全不同的功能。
class WeirdNamesPlayer
{
void BeginPlayback() { // plays}
void Terminate() { // stops }
void Randomize() { // shuffles }
}
你所做的是创建一个 "wrapper" 来实现你的 IPlayer
,并让它包装你的 WeirdNames
。
class WeirdPlayerAdapter : IPlayer
{
private readonly WeirdNamesPlayer weird;
public WeirdPlayerAdapter(WeirdNamesPlayer weird)
{
this.weird = weird;
}
void Play()
{
this.weird.BeginPlayback();
}
void Stop()
{
this.weird.Terminate();
}
void Shuffle()
{
this.weird.Randomize();
}
}
现在您可以自由使用不兼容的实现来代替 IPlayer
-- 适配器提供了所需的接口。
我努力创建了一个适配器设计模式。一个简单的界面,用户可以使用它连接到旧的和现代的媒体播放器。
现代媒体播放器播放 mp4
格式,而旧播放器仅播放 wav
格式。使用 class mediaPlayerInterface 用户可以播放两种媒体类型。
如果您觉得这不是适配器设计模式,请评论缺少的内容。如何将其修改为适配器模式?我对设计模式有点陌生。
#include <iostream>
#include <string>
using namespace std;
class MediaPlayer
{
public:
virtual void playSong()=0;
};
class ModernMediaPlayer : public MediaPlayer
{
public:
void playSong( )
{
cout << "Playing from modern media player" << endl;
}
};
class oldMediaPlayer: public MediaPlayer
{
public:
void playSong( )
{
cout << "Playing from old media player" << endl;
}
};
class mediaPlayerInterface
{
private:
string fileType;
public:
mediaPlayerInterface(string fType)
{
fileType=fType;
}
MediaPlayer* getMediaPlayer( )
{
if (fileType == "mp4")
{
return new ModernMediaPlayer;
}
else if (fileType == "wav")
{
return new oldMediaPlayer;
}
}
};
int main()
{
mediaPlayerInterface *mIface = new mediaPlayerInterface("mp4");
MediaPlayer *mplayer = mIface->getMediaPlayer();
mplayer->playSong();
mIface = new mediaPlayerInterface("wav");
mplayer = mIface->getMediaPlayer();
mplayer->playSong();
}
Output:
Playing from modern media player
Playing from old media player
下面是一个适配器模式的例子。重要的是 AscSequenceControl 具有所有必需的功能,但它不能连接到 MovementPlanner,因为接口不兼容。所以RouteSegmenter确实是"adapts"这个。它具有正确的接口,其实现仅使用 AscSequenceControl。
因此在您的示例中:您有一个 MediaPlayer,其方法为:gotoTrack (int trackNr)。但是 class MediaPlayerUser 想说的是:mediaPlayer.nextTrack() 和 mediaPlayer.previousTrack()。所以你做了一个桥 class MediaPlayerBridge。它有一个属性 mediaPlayer 和调用 mediaPlayer.gotoTrack (++currentTrack) 的方法 nextTrack 和一个调用 mediaPlayer.gotoTrack (--currentTrack) 的方法 previousTrack。
嗯,适配器模式的基本思想是(我不懂C++,所以请原谅我的C#代码)--
你针对抽象进行编程
interface IPlayer
{
void Play();
void Stop();
void Shuffle();
}
class ModernPlayer : IPlayer
{
void Play() { // plays }
void Stop() { // stops }
void Shuffle() { // shuffles }
}
到目前为止一切顺利。你在你的代码中使用它,比如
IPlayer player = GetPlayer(); // some way to get an abstract IPlayer
player.Shuffle();
然后您意识到您需要一个不同的 IPlayer 实现。你找到一个有播放器的图书馆,但它有一套完全不同的功能。
class WeirdNamesPlayer
{
void BeginPlayback() { // plays}
void Terminate() { // stops }
void Randomize() { // shuffles }
}
你所做的是创建一个 "wrapper" 来实现你的 IPlayer
,并让它包装你的 WeirdNames
。
class WeirdPlayerAdapter : IPlayer
{
private readonly WeirdNamesPlayer weird;
public WeirdPlayerAdapter(WeirdNamesPlayer weird)
{
this.weird = weird;
}
void Play()
{
this.weird.BeginPlayback();
}
void Stop()
{
this.weird.Terminate();
}
void Shuffle()
{
this.weird.Randomize();
}
}
现在您可以自由使用不兼容的实现来代替 IPlayer
-- 适配器提供了所需的接口。