StarryNights

每一个你所后悔的现在,都有一个不够努力的曾经

站内检索

循着字句,邂逅星光

搜索文章标题与正文,直达命中的章节

开始一次轻盈的站内探索

从这些主题开始探索

输入关键词

可同时输入多个词语缩小范围

发现内容

在摘要中查看高亮的关键词

快速直达

点击文章或章节标题继续阅读

# Adapter模式简介

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于 结构型模式, 它结合了两个独立接口的功能。将一个类的接口转换成客户希望的另一个接口。使得原本由于接口不兼容而不能一起工作的类可以一起工作。

这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。

举个栗子

现在手机充电接口开始向 Type-C 转变,但是市面上大多数充电线还是传统的接口,如果你有没有针对性的 Type-C 充电线,怎么办呐,答案是显而易见的用转接头, 转换接口, 从而可以利用传统数据线为 Type-C 接口的手机充电。适配器模式就是利用这个单一的类, 充当转接头的作用,让其他的类, 能够适配我们新的要求, 而不用为了这个新标准而重构大量代码。

# 结构与分类

Adapeter模式主要有两种类型 对象Adapter模式 和 类Adapter模式

# 对象Adapter模式

如下图所示,这种结构依赖于一个对象(适配对象)包含另外的一个对象(被适配的对象),就好比UML图中展示的那样,在派生类Adapter中引用Adaptee(被适配对象),调用其中的相关函数,实现接口与结构的统一。

Adapter_Pattern_UML

# 类Adapter模式

这种结构的通过 多继承的方式来实现 的一般从定义其接口的抽象类公开继承,从访问其实现的原有类私有继承, 具体可参照下图

Adapter_Pattern_Class_UML

# 具体实现

音频播放器的扩展

  1. 我们有一个 IAudioPlayer 接口和一个实现了 IAudioPlayer 接口的实体类 AudioPlayer。默认情况下,AudioPlayer 可以播放 mp3 格式的音频文件。
  2. 我们还有另一个接口 IAdvancedMediaPlayer 和实现了 IAdvancedMediaPlayer 接口的实体类。该类可以播放 wav 和 ape 格式的高级音频文件。
  3. 我们想要让 AudioPlayer 播放其他格式的音频文件。为了实现这个功能,我们需要创建一个实现了 IAudioPlayer 接口的适配器类 AudioAdapter, 并使用 IAdvancedMediaPlayer 对象来播放所需的格式。
  4. AudioPlayer 使用适配器类 AudioAdapter 传递所需的音频类型,不需要知道能播放所需格式音频的实际类。Adapter Pattern,我们的演示类使用 AudioPlayer 类来播放各种格式。

具体UML类图如下 直接在VS2015的建模项目里画的,方便我直接生成部分代码,与标准UML图可能有差异

Adapter-Patterneg

# Step1: 为音频播放器和更高级的音频播放器创建接口

IAudioPlayre.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Adapter_Pattern_适配器模式_
{
    public interface IAudioPlayer
    {
        void player(string audioType, string fileName);
    }
}

IAdvanceAudioPlayer.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Adapter_Pattern_适配器模式_
{
    //高级音频格式播放
    public interface IAdvanceAudioPlayer
    {
        void playWav(string fileName);
        void playApe(string fileName);
    }
}

# Step2: 创建实现了 IAdvancedMediaPlayer 接口的实体类

WavPlayer.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Adapter_Pattern_适配器模式_
{
    class WavPlayer : IAdvanceAudioPlayer
    {
        public void playApe(string fileName)
        {
            //什么也不做
            throw new NotImplementedException();
        }

        public void playWav(string fileName)
        {
            Console.WriteLine("Playing wav file. Name:" + fileName);
        }
    }
}

ApePlayer.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Adapter_Pattern_适配器模式_
{
    class ApePlayer : IAdvanceAudioPlayer
    {
        public void playApe(string fileName)
        {
            Console.WriteLine("Playing ape file. Name:" + fileName);
        }

        public void playWav(string fileName)
        {
            //什么也不做
            throw new NotImplementedException();
        }
    }
}

# Step3: 创建实现了 AduioPlayer 接口的适配器

AudioAdapter.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Adapter_Pattern_适配器模式_
{
    //高级音频播放的适配器
    class AudioAdapter : IAudioPlayer
    {
        private IAdvanceAudioPlayer advancedAudioPlayer;
        public AudioAdapter (string audioType)
        {
            if(audioType=="ape")
            {
                advancedAudioPlayer = new ApePlayer();
            }
            else if(audioType =="wav")
            {
                advancedAudioPlayer = new WavPlayer();
            }
        }

        public void player(string audioType, string fileName)
        {
            if(audioType=="ape")
            {
                advancedAudioPlayer.playApe(fileName);
            }
            else if(audioType=="wav")
            {
                advancedAudioPlayer.playWav(fileName);
            }
        }
    }
}

# Step4: 创建实现了 AudioPlayer 接口的基本音频格式播放的实体类

AudioPlayer.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Adapter_Pattern_适配器模式_
{
    class AudioPlayer : IAudioPlayer
    {
        private AudioAdapter audioAdapter;
        public void player(string audioType, string fileName)
        {
            if(audioType=="mp3")
            {
                Console.WriteLine("Playing mp3 file. Name:" + fileName);
            }
            else if(audioType=="ape"||audioType=="wav")
            {
                audioAdapter = new AudioAdapter(audioType);
                audioAdapter.player(audioType, fileName);
            }
            else
            {
                Console.WriteLine("Invalid audio. " + audioType + " format not supported");
            }
        }
    }
}

# Step5: 一个驱动类利用 AudioPlayer 来播放不同格式的音频文件

AdapterPattern.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Adapter_Pattern_适配器模式_
{
    class AdapterPattern
    {
        static void Main(string[] args)
        {
            AudioPlayer audioPlayer = new AudioPlayer();
            audioPlayer.player("mp3", "beyond the horizon.mp3");
            audioPlayer.player("wav", "alone.wav");
            audioPlayer.player("ape", "my heart will go on.ape");
            audioPlayer.player("vlc", "far far away.vlc");
        }
    }
}

输出结果

Playing mp3 file. Name:beyond the horizon.mp3
Playing wav file. Name:alone.wav
Playing ape file. Name:my heart will go on.ape
Invalid audio. vlc format not supported

# 样例代码下载地址

更新于 阅读次数 — 次
STARRY NIGHTSPERSONAL NOTES

赞赏

文章至此,故事还在继续。

Seiun

长按或右键保存收款码