神刀安全网

公司新加了一台友宝自动售货机引发的思考-适配者模式

一、前沿

公司茶水间不知道什么时候新增了一个友宝自动售货机,里面的饮料比外面的价格便宜很多(几乎是半价啦)。兴冲冲的去点击金罐多加宝,价格3.5元,付钱发现没有带钱包,幸好带了手机可以微信、支付宝、QQ支付好牛逼的自动售货机。

无图无真相,下面直接上支付时候的图

公司新加了一台友宝自动售货机引发的思考-适配者模式

二、基本概念

适配器模式(Adapter Pattern) :将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。

适配器模式包含四个角色:

目标接口(Target):客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。

需要适配的类(Adaptee):需要适配的类或适配者类。

适配器(Adapter):通过包装一个需要适配的对象,把原接口转换成目标接口。

客户类 (Client):客户端调用

书上对适配器模式讲了两种类型,类适配器模式和对象适配器模式。由于类适配器模式通过多重继承对一个接口与另一个接口进行匹配,而C#、java等语言都不支持多重继承,因而这里只是介绍对象适配器。

三、代码示例

基本代码示例

 /// <summary>         /// 目标抽象类角色         /// </summary>         public class Target         {             public virtual void Request()             {                 Console.WriteLine("This is a common request");             }         }          /// <summary>         /// 适配者类角色         /// </summary>         public class Adaptee         {             public void SpecificRequest()             {                 Console.WriteLine("This is a special request.");             }         }          /// <summary>         /// 适配器角色         /// </summary>         public class Adapter : Target         {             // 建立一个私有的Adeptee对象             private Adaptee adaptee = new Adaptee();              /// <summary>             /// 通过重写,表面上调用Request()方法,变成了实际调用SpecificRequest()             /// </summary>             public override void Request()             {                 adaptee.SpecificRequest();             }         }          static void Main(string[] args)         {             // 对客户端来说,调用的就是Target的Request()             Target target = new Adapter();             target.Request();              Console.ReadKey();         } 

输出结果:This is a special request.

自动售货机代码示例说明适配器模式:

        //目标抽象类角色:支付接口         public interface IPay         {             void Pay();         }          //适配者角色:支付宝支付、财付通支付、微信支付、现金支付         public class Alipay : IPay         {             public void Pay()             {                 Console.WriteLine("支付宝支付");             }         }          public class Tenpay : IPay         {             public void Pay()             {                 Console.WriteLine("QQ支付");             }         }          public class WeixinPay : IPay         {             public void Pay()             {                 Console.WriteLine("微信支付");             }         }          public class CashPay : IPay         {             public void Pay()             {                 Console.WriteLine("现金支付");             }         }            /// <summary>         /// 适配器角色:适配支付宝支付         /// </summary>         public class AliAdapter         {             IPay _pay = new Alipay();             public void Pay()             {                 _pay.Pay();             }         }         /// <summary>         /// 适配器角色:适配财付通支付         /// </summary>         public class TenAdapter         {             IPay _pay = new Tenpay();             public void Pay()             {                 _pay.Pay();             }         }         /// <summary>         /// 适配器角色:适配微信支付         /// </summary>         public class WeixinAdapter         {             IPay _pay = new WeixinPay();             public void Pay()             {                 _pay.Pay();             }         }         /// <summary>         /// 适配器角色:适配现金支付         /// </summary>         public class CashAdapter         {             IPay _pay = new CashPay();             public void Pay()             {                 _pay.Pay();             }         }           static void Main(string[] args)         {             //// 对客户端来说,调用的就是Target的Request()             //Target target = new Adapter();             //target.Request();              //支付宝支付             IPay alipay = new Alipay();             alipay.Pay();              //现金支付             IPay cashPay = new CashPay();             cashPay.Pay();              //财付通支付             IPay tenpay = new Tenpay();             tenpay.Pay();              //微信支付             IPay weixinPay = new WeixinPay();             weixinPay.Pay();              Console.ReadKey();         } 

四、总结

优点:

将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,而无须修改原有代码。

增加了类的透明性和复用性,将具体的实现封装在适配者类中,对于客户端类来说是透明的,而且提高了适配者的复用性。

灵活性和扩展性都非常好,通过使用配置文件,可以很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器类,完全符合“开闭原则”。

应用举例:

电脑适配器

ADO.NET中的DataAdapter

五、最后上个全图

公司新加了一台友宝自动售货机引发的思考-适配者模式

代码下载:https://yunpan.cn/cYDJqjtTd5Uea (提取码:b4dd)

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » 公司新加了一台友宝自动售货机引发的思考-适配者模式

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址