Adapter模式简介
适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。将一个类的接口转换成客户希望的另一个接口。使得原本由于接口不兼容而不能一起工作的类可以一起工作。
这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。
举个栗子:现在手机充电接口开始向Type-C转变,但是市面上大多数充电线还是传统的接口,如果你有没有针对性的Type-C充电线,怎么办呐,答案是显而易见的用转接头,转换接口,从而可以利用传统数据线为Type-C接口的手机充电。
适配器模式就是利用这个单一的类,充当转接头的作用,让其他的类,能够适配我们新的要求,而不用为了这个新标准而重构大量代码。
结构与分类
Adapeter模式主要有两种类型 对象Adapter模式 和 类Adapter模式
1.对象Adapter模式:
如右图所示,这种结构依赖于一个对象(适配对象)包含另外的一个对象(被适配的对象),就好比UML图中展示的那样,在派生类Adapter中引用Adaptee(被适配对象),调用其中的相关函数,实现接口与结构的统一。
2.类Adapter模式:
这种结构的通过多继承的方式来实现的,一般从定义其接口的抽象类公开继承,从访问其实现的原有类私有继承,具体可参照下图
具体实现
音频播放器的扩展
1)我们有一个 IAudioPlayer 接口和一个实现了 IAudioPlayer 接口的实体类 AudioPlayer。默认情况下,AudioPlayer 可以播放 mp3 格式的音频文件。
2)我们还有另一个接口 IAdvancedMediaPlayer 和实现了 IAdvancedMediaPlayer 接口的实体类。该类可以播放 wav 和 ape 格式的高级音频文件。
3)我们想要让 AudioPlayer 播放其他格式的音频文件。为了实现这个功能,我们需要创建一个实现了 IAudioPlayer 接口的适配器类 AudioAdapter,并使用 IAdvancedMediaPlayer 对象来播放所需的格式。
4)AudioPlayer 使用适配器类 AudioAdapter 传递所需的音频类型,不需要知道能播放所需格式音频的实际类。Adapter Pattern,我们的演示类使用 AudioPlayer 类来播放各种格式。
Step1:为音频播放器和更高级的音频播放器创建接口。
IAudioPlayre.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
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"); } } } |
输出结果
1 2 3 4 |
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 |