设计模式6 - 适配器模式

作者: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
  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值