代码改变世界

结合项目实例 回顾传统设计模式(七)适配器模式(附外观模式)

2011-10-06 09:38  熬夜的虫子  阅读(709)  评论(0编辑  收藏  举报

记得以前章节谈过的装饰者模式,我们将对象包装起来,赋予他们新的职责。而现在则是以不同目的,包装某些对象:让他们的接口看起来不像自己而像是别的东西。这样就可以在设计中,将类的接口转换成想要的接口,以便实现不同的接口。

在项目中,适配器模式一般扮演者协调者的作用。

1.客户通过目标接口调用适配器的方法对适配器发出请求

2.适配器使用被适配者接口把请求转换成被适配者的一个或多个调用接口

3.客户接受到调用的结果,但并未察觉这一切是适配器在起转换作用

另外还有一种特殊情况,万一系统新旧并存,旧的部分期望旧的厂商接口,但我们却已经使用新厂商的接口编写了这一部分,这个时候该怎么办?这里使用适配器,那里却使用未包装的接口,这实在让人感到混乱。这种情况需要创建一个双向的适配器,支持两边的接口。

关于这一节的项目 咱们就选银行支付驱动

/// <summary>
    
/// 支付驱动
    
/// </summary>
    public interface PayChannelDriver
    {
        void PayCallBack();

        string ReplaceHtmlCode(string order_no, string order_create_time,string currency, string extra, string goods_desc);
       
    }

    /// <summary>
    
/// 银行支付驱动
    
/// </summary>
    public class CMBPayChannelDriver : PayChannelDriver
    {
        public void PayCallBack()
        {
            Console.WriteLine("this is CMBPayChannelDriver");
        }

        public string ReplaceHtmlCode(string order_no, string order_create_time, string currency, string extra, string goods_desc)
        {
            return "";
        }
    }

    /// <summary>
    
/// 第三方支付驱动
    
/// </summary>
    public class OtherPayChannelDriver 
    {
        public void OtherPayCallBack()
        {
            Console.WriteLine("this is OtherPayChannelDriver");
        }

        public string GetReuqestUrl(string order_no, string order_create_time, string goods_desc)
        {
            return "";
        }
    }

    /// <summary>
    
/// 适配器
    
/// </summary>
    public class PayChannelDriverAdapter : PayChannelDriver
    {
        OtherPayChannelDriver ocd;
        public PayChannelDriverAdapter(OtherPayChannelDriver otherpcd)
        {
            this.ocd = otherpcd;
        }
        public void PayCallBack()
        {
            ocd.OtherPayCallBack();
        }
        public string ReplaceHtmlCode(string order_no, string order_create_time,string currency, string extra, string goods_desc)
        {
            return ocd.GetReuqestUrl(order_no, order_create_time,goods_desc);
        }
 
    }

 

测试看看

          //普通银行驱动
           PayChannelDriver pd = new CMBPayChannelDriver();
           //第三方支付不支持银行驱动
           OtherPayChannelDriver od = new OtherPayChannelDriver();
           //适配器
           PayChannelDriver apd = new PayChannelDriverAdapter(od);
           //驱动支持适配器
           pd.PayCallBack();
           apd.PayCallBack();

 

总结:适配器模式将一个类的接口转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。

设计原则: 当你正在设计一个系统,不管是任何对象,你都要注意它所交互的类有哪些,并注意它和这些类是如何交互的。不要让太多的类耦合在一起,免得修改系统中一部分,会影响到其他部分。如果许多类之间相互依赖,那么这个系统就会变成一个易碎的系统,它需要花许多成本维护,也会因为太复杂而不容易被其他人了解。

下面我们再看看外观模式

在适配器模式中一个适配器只能够封装一个类吗?适配器模式的工作是将一个借口转换成另一个。虽然大多数的适配器模式所采取的例子都是让一个适配器包装一个被适配者,但我们都知道这个世界其实复杂多了,需要让一个适配器包装多个被适配者。这就涉及到外观模式。

外观模式提供一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。实例的话就不再赘述了。

总得来说 外观模式基于适配器模式让接口变得更简单。