设计模式:适配器与装饰器
装饰器模式
我们常常面临一个问题,在原有的功能上进行扩展,如何优雅的进行实现?
有人会说,给这个类加一个新方法不就得了。这不就违背了开闭原则吗?类应该对扩展开放,对修改封闭。
一般常见有两种方式,一是直接继承于想要扩展的类,那么我们就能够在原有功能的基础上,扩展更多的方法。下面将进行简单实现:
  class Phone
    {
        void Call()
        {
            
        }
        void SendMessage()
        {
            
        }
    }
    class MusicPhone : Phone
    {
        void PlayMusic()
        {
            
        }
    }
    class GamePhone : Phone
    {
        void PlayGame()
        {
            
        }
    }
我们申明了一个手机类,它初始只有两个功能,打电话和发短信。
然后我们通过继承,给这个手机增加了播放音乐的功能。同时,我们还造了一部能玩游戏的手机。
缺点
装饰器模式能够很好的帮助我们对一个类进行扩展,并且符合开闭原则。但是随着功能越来越多,静态的通过继承来进行实现,会造成代码量迅速膨胀
同时通过以下方法也是可行的,并且可以有效解决继承带来的弊端。:
     interface IPhone
    {
        void Call();
        void SendMessage();
    }
    class Phone : IPhone
    {
        public void Call()
        {
        }
        public void SendMessage()
        {
        }
    }
    class MediaPhone : IPhone
    {
        private readonly IPhone _phone;
        public MediaPhone(IPhone phone)
        {
            _phone = phone;
        }
        void PlayMusic()
        {
        }
        void PlayGame()
        {
        }
        public void Call()
        {
            _phone.Call();
        }
        public void SendMessage()
        {
            _phone.SendMessage();
        }
    }
通过关联某一个类,然后在此基础上进行扩展。
C#还有一个装饰模式利器,那就是静态扩展方法。同样还是手机的例子:
class Program
    {
        static void Main(string[] args)
        {
            var phone = new Phone();
            phone.PlayMusic();
        }
    }
    class Phone
    {
        void Call()
        {
        }
        void SendMessage()
        {
        }
    }
    static class PhoneExtension
    {
        public static void PlayMusic(this Phone phone)
        {
        }
    }
通过一个静态类,实现一个静态方法,就可以达到扩展的目的,这种方式被官方类库广泛使用,最常见的就是Linq程序集下对IEnumable接口的扩展了。
适配器模式
如果装饰器模式是为了扩展,那么适配器模式就是为了兼容。
虽然我们普遍存在接口,只要我们依赖同样的接口,就能无需关心实现。但是如果接口层次不兼容如何解决呢?修改接口的话,会对代码进行侵入性的更改。
通过适配器模式,可以较好的解决这个问题。
还是手机的例子:
 class Program
    {
        static void Main(string[] args)
        {
            var phone = new Phone();
            IWatch adapter = new WatchAdapter(phone);
            TellMeTime(adapter);
        }
        static void TellMeTime(IWatch watch)
        {
            watch.ShowTime();
        }
    }
    interface IPhone
    {
        void Call();
        void SendMessage();
        void ShowTime();
    }
    class Phone : IPhone
    {
        public void Call()
        {
        }
        public void SendMessage()
        {
        }
        public void ShowTime()
        {
        }
    }
    interface IWatch
    {
        void ShowTime();
    }
    class WatchAdapter : IWatch
    {
        private readonly IPhone _phone;
        public WatchAdapter(IPhone phone)
        {
            _phone = phone;
        }
        public void ShowTime() => _phone.ShowTime();
    }
我们的程序需要一个手表来显示时间,但是现在没有手表,找来找去,发现只有手机可以用,并且用它来显示时间也是合适的。可是TellMeTime方法接收的参数是IWatch类型,手机并没有实现这个接口。此时我们就可以使用一个Adapter来封装一下手机,并且实现IWatch接口,即可满足我们的需求。
总结
装饰器模式主要应用于扩展,扩展丰富了类的功能,但却并不是类的一部分。他们之间是没有必然关系的。
适配器是为了解决两个不兼容的类或接口,使他们能够正常的进行功能配合而生。
- 0
 - 0
 - 
              
              
  
分享