这是正确实施的适配器设计模式吗?如果不是,我错过了什么?

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 -- 适配器提供了所需的接口。