之前和大家一起谈了工厂模式和单例模式,今天来看一下另一种非常常用的模式,它就是适配器模式,第一次看到这个模式是通过“张逸”老师的“设计之道”这篇文章,在这里表adapter讲的很透彻,今天把张老师的文章拿过来,分享给大家!
何时能用到它?
对于一个软件生产商A来说,在过去的20年里,它们主要生产收音机,包括最早的老式半导体和现代的数字收音机,总之,是收音机。但不知道从什么时候开始,MP4媒体播放器出现了,这使得A生产商不得不去招新人,去生产适合大家的mp4播放器,这东西很好,能听音乐,看电影,比20年前的收音机好多了!
正在A生产商洋洋得意时,突然有个客户投诉他们,说你们的东西为何没有收音机的功能,我想叫广播!这下可让A生产商发愁了,它马上找到了公司的技术总监,CTO是个很厉害的岗位,它们无所不能,只要你有需求,我们就可以给你实现!CTO是如何让mp4播放器具体收音机功能的呢?大家继续看
适配器模式的结构图
适配器模式实现说明
媒体播放接口IMedia
视频实现抽象类VideoMedia
音频实现抽象类AudioMedia
mp4播放器实现类:mp4Media和mp3Media,可能还有FlvMedia等
收音机接口IRadio
收音机抽象类Radio
收音机FM调频实现类FmRadio
收音机FM调频与媒体播放器的适配器FmAdapter
适配器模式的C#实现
#region adapter[播放器适配器]
#region 媒体播放器
interface IMedia
{
void Play();
void Stop();
void Next();
void Prev();
void Pause();
void OpenFile();
void CloseFile();
}
abstract class AudioMedia : IMedia
{
public virtual void Play()
{
throw new NotImplementedException();
}public void Stop()
{
throw new NotImplementedException();
}public void Next()
{
throw new NotImplementedException();
}public void Prev()
{
throw new NotImplementedException();
}public void Pause()
{
throw new NotImplementedException();
}public void OpenFile()
{
throw new NotImplementedException();
}public void CloseFile()
{
throw new NotImplementedException();
}
}
abstract class VideoMedia : IMedia
{
public virtual void Play()
{
throw new NotImplementedException();
}public void Stop()
{
throw new NotImplementedException();
}public void Next()
{
throw new NotImplementedException();
}public void Prev()
{
throw new NotImplementedException();
}public void Pause()
{
throw new NotImplementedException();
}public void OpenFile()
{
throw new NotImplementedException();
}public void CloseFile()
{
throw new NotImplementedException();
}
}
class Mp3Media : AudioMedia
{
public override void Play()
{
base.Play();
Console.WriteLine("播放mp3");
}
}
class Mp4Media : VideoMedia
{
public override void Play()
{
base.Play();
Console.WriteLine("播放mp4");
}
}
#endregion
#region 收音机
interface IRadio
{
void Receive();
void Stop();
void TurnOn();
void TurnOff();
void Change(bool direction);
}
abstract class Radio : IRadio
{
public virtual void Receive()
{
throw new NotImplementedException();
}public void Stop()
{
throw new NotImplementedException();
}public void TurnOn()
{
throw new NotImplementedException();
}public void TurnOff()
{
throw new NotImplementedException();
}public virtual void Change(bool direction)
{
throw new NotImplementedException();
}
}
class FmRadio : Radio
{
public override void Receive()
{
base.Receive();
Console.WriteLine("接口FM频段");
}
public override void Change(bool direction)
{
base.Change(direction);
Console.WriteLine("改变FM频段");
}
}
#endregion
#region 收音机到媒体播放器的适配器
class FMAdapter : Radio, IMedia
{
//! 适配器通过Radio去实现了IMedia接口public void Play()
{
base.TurnOn();
base.Receive();
}public void Stop()
{
base.TurnOff();
}public void Next()
{
base.Change(true);}
public void Prev()
{
base.Change(false);
}public void Pause()
{
throw new NotImplementedException();
}public void OpenFile()
{
throw new NotImplementedException();
}public void CloseFile()
{
throw new NotImplementedException();
}
}
#endregion
#endregion
这样我们就实现了Radio与Media两大对象的联系,而这种联系是在不破坏对象本身的基础上实现的,这种实现的过程就是适配器模式实现的过程!
感谢GOF,感谢张逸老师!