zoukankan      html  css  js  c++  java
  • 公司新加了一台友宝自动售货机引发的思考-适配器模式

    设计模式相关文章

    一、前言

    公司茶水间不知道什么时候新增了一个友宝自动售货机,里面的饮料比外面的价格便宜很多(几乎是半价啦)。兴冲冲的去点击金罐多加宝,价格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 { public void Ali_Pay() { Console.WriteLine("支付宝支付"); } } public class Tenpay { public void Ten_Pay() { Console.WriteLine("QQ支付"); } } public class WeixinPay { public void Wenxin_Pay() { Console.WriteLine("微信支付"); } } public class CashPay { public void Cash_Pay() { Console.WriteLine("现金支付"); } } /// <summary> /// 适配器角色:适配支付宝支付 /// </summary> public class AliAdapter : Alipay, IPay { public void Pay() { base.Ali_Pay(); } } /// <summary> /// 适配器角色:适配财付通支付 /// </summary> public class TenAdapter : Tenpay, IPay { public void Pay() { base.Ten_Pay(); } } /// <summary> /// 适配器角色:适配微信支付 /// </summary> public class WeixinAdapter : WeixinPay, IPay { public void Pay() { base.Wenxin_Pay(); } } /// <summary> /// 适配器角色:适配现金支付 /// </summary> public class CashAdapter : CashPay, IPay { public void Pay() { base.Cash_Pay(); } } static void Main(string[] args) { //// 对客户端来说,调用的就是Target的Request() //Target target = new Adapter(); //target.Request(); //支付宝支付 IPay alipay = new AliAdapter(); alipay.Pay(); //现金支付 IPay cashPay = new CashAdapter(); cashPay.Pay(); //财付通支付 IPay tenpay = new TenAdapter(); tenpay.Pay(); //微信支付 IPay weixinPay = new WeixinAdapter(); weixinPay.Pay(); Console.ReadKey(); }

    输入结果:

    四、总结

    优点:

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

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

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

    应用举例:

    电脑适配器

    ADO.NET中的DataAdapter

    五、最后上个全图

     代码下载:https://yunpan.cn/cYDYwAJM5KBCw (提取码:2656)

  • 相关阅读:
    Eclipse 3.0.1插件方案(Java版) zt
    Vs2003使用时出现这个问题,正在郁闷中,网上找了好久,居然看到同样问题,马上拷贝来:)开心中
    Eclipse+Tomcat集成开发servletzt
    管理定律
    张小娴“禁果之味”
    上海主要特色医院一览表
    分布式网站数据库同步方案——sqlserver数据库同步复制,好文收藏之
    Eclipse 插件汇总(转载+不断更新) zt
    Eclipse零起步系列讲座 zt
    结婚这件事
  • 原文地址:https://www.cnblogs.com/yinrq/p/5300820.html
Copyright © 2011-2022 走看看