首页 > 代码库 > 说说设计模式~适配器模式

说说设计模式~适配器模式

之前和大家一起谈了工厂模式和单例模式,今天来看一下另一种非常常用的模式,它就是适配器模式,第一次看到这个模式是通过“张逸”老师的“设计之道”这篇文章,在这里表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,感谢张逸老师!