今天看到一个园子里的朋友写了一篇ASP.NET的适配器设计模式的文章。其中提到了把输入的电压转换成灯泡适合的电压,这样才能使灯泡正常工作。正巧,我也在学习设计模式,其中翻看了一下秦小波写的《设计模式与禅》这本书,其中提到了设计模式的定义为:

将一个类的接口变成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够一起工作。

适配器模式又叫变压器模式,也叫包装模式。

这里作者举得例子并没有实现把一个接口或类转换到另外一个可以使用的类,仅仅是把输入参数做了判断,这是不是适配器模式我不予置评,下面贴出我实现的适配器模式。

我们知道,中国的电压是220V,而日本的电压为110V,我们中国生产的电灯泡一般额定电压为220V,如果想要这个灯泡在日本能够正常工作就必须使用一个适配器,把110V电压转换成220V电压。

定义接口代码如下:

 
  
  1. using System;  

  2. using System.Collections.Generic;  

  3. using System.Linq;  

  4. using System.Text;  

  5. namespace HelloWorld  

  6. {  

  7. /// <summary>

  8. /// 中国电接口

  9. /// </summary>

  10. publicinterface IChinaElectricity  

  11.    {  

  12. /// <summary>

  13. /// 电压

  14. /// </summary>

  15. /// <returns></returns>

  16. int Voltage();  

  17.    }  

  18. /// <summary>

  19. /// 日本电接口

  20. /// </summary>

  21. publicinterface IJapanElectricity  

  22.    {  

  23. /// <summary>

  24. /// 电压

  25. /// </summary>

  26. /// <returns></returns>

  27. int Voltage();  

  28.    }  

  29. /// <summary>

  30. /// 灯接口

  31. /// </summary>

  32. publicinterface IChinaLight  

  33.    {  

  34. /// <summary>

  35. /// 发光

  36. /// </summary>

  37. /// <returns></returns>

  38. string Light(int voltage);  

  39.    }  

  40. }

定义的类如下:

 
  
  1. using System;  

  2. using System.Collections.Generic;  

  3. using System.Linq;  

  4. using System.Text;  

  5. namespace HelloWorld  

  6. {  

  7.    public class ChinaElectricity : IChinaElectricity  

  8.    {  

  9.        public int Voltage()  

  10.        {  

  11. return 220;  

  12.        }  

  13.    }  

  14.    public class JapanElectricity : IJapanElectricity  

  15.    {  

  16.        public int Voltage()  

  17.        {  

  18. return 110;  

  19.        }  

  20.    }  

  21.    public class ChinaLight : IChinaLight  

  22.    {  

  23.        /// <summary>  

  24.        /// 发光  

  25.        /// </summary>  

  26.        /// <returns></returns>  

  27.        public string Light(int voltage)  

  28.        {  

  29. if (voltage == 220)  

  30.            {  

  31. return"我发光啦....";  

  32.            }  

  33. else

  34.            {  

  35. return ("电压不正确,无法正常工作...");  

  36.            }  

  37.        }  

  38.    }  

  39.    /// <summary>  

  40.    /// 定义一个电压适配器  

  41.    /// </summary>  

  42.    public class ElectricityAdapter : IChinaElectricity  

  43.    {  

  44.        private int voltage = 0;  

  45.        private IJapanElectricity iJElectricity = null;  

  46.        public ElectricityAdapter(IJapanElectricity _baseElectricity)  

  47.        {  

  48.            iJElectricity = _baseElectricity;  

  49.            voltage = this.iJElectricity.Voltage();  

  50.        }  

  51.        public int Voltage()  

  52.        {  

  53. return voltage + 110;  

  54.        }  

  55.    }  

  56. }

这里面我们定义了一个适配器的类,把日本电压适配成中国电压,这样才能够使灯泡正常工作。代码如下:

 
  
  1. staticvoid Main(string[] args)  

  2.        {  

  3. //初始化一个中国电灯

  4.            IChinaLight iCLight = new ChinaLight();  

  5. //初始化中国的电

  6.            IChinaElectricity iCElectricity = new ChinaElectricity();  

  7. //初始化日本电

  8.            IJapanElectricity iJElectricity =new JapanElectricity();  

  9. //使用适配器

  10.            IChinaElectricity iCAElectricity = new ElectricityAdapter(iJElectricity);  

  11. //电压正确电灯发光

  12.            Console.WriteLine(iCLight.Light(iCElectricity.Voltage()));  

  13. //使用电压适配器进行适配

  14.            Console.WriteLine(iCLight.Light(iCAElectricity.Voltage()));  

  15. //电压不正确,电灯产生异常

  16.            Console.WriteLine(iCLight.Light(iJElectricity.Voltage()));  

  17.        }

通过适配器模式的定义可以知道,其实适配器模式无非是把一种已经无法修改,或是修改成本较高的源角色通过适配角色转换成目标角色,这样整个业务体系才能够在代价最小的情况下进行正常运行。

适配器模式的优点:

适配器模式可以让两个没有任何关系的类在一起运行,只要适配器这个角色能够搞定他们就行。

  • 增加了类的透明性。

  • 提高了类的复用度。

  • 灵活性非常好。

适配器模式的使用场景:

适配器应用场景只要记住一点就足够了:你有动机修改一个已经投产中的接口时,适配器模式可能是最适合你的模式。比如系统扩展了,只需要一个已有或新建立的类,但这个类又不符合系统的接口,这个时候使用适配器模式比修改已存在的类代价要小的多。