致我们工作中的设计模式之适配器模式

在《大话设计模式》中大鸟和小菜是通过姚明刚加入火箭队时候英文不好,需要一个中间翻译来沟通,就类似于软件设计中的适配器模式一样,引入话题的。Adapter,将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的类可以一起工作。

         对于这个模式我是身有体会,因为在曾经开发电子商务系统的时候,需要同客户的淘宝网店、客户的ERP系统数据建立数据交互,然后淘宝接口中取的数据有淘宝自己的数据格式,与淘宝的数据交互主要是订单信息和订单收货人信息,而同客户ERP交互的主要是基础库信息,如产品、门店等信息。自身的系统同样建立了会员、门店、产品、订单等信息表,也同样建立由此展开的业务逻辑类、数据Model、以及访问接口类。这样一来的话,以订单信息为例,淘宝接口返回的数据有订单数据的Model,ERP实体门店订单数据的Model和电商自身的订单Model又是截然不同的,而由此导致的订单业务逻辑操作也是不同的。

就以这个应用为例,我们以电商为核心,因为这个是需要继续完善和拓展的,而淘宝和ERP我们都暂时认为是需要接入的系统,那么如何在自己的电商系统中完美无缝的连接入淘宝、ERP的数据,以及如何完整没有隔阂的访问这两类订单数据呢。

实体类代码:

    public class MemberInfo
    {
        public string MmbrInfoID { get; set; }
        public string MmbrInfoName { get; set; }
    }

    public class Taobao_TransactionH
    {
        public string TransHID { get; set; }
        public string StoreCode { get; set; }
        public string Receiver_name { get; set; }
    }

    public class ERPDD
    {
        public string DDID { get; set; }
        public string HYID { get; set; }
    }

    public class Order_Info
    {
        public string OrderID { get; set; }
        public string MmbrInfoID { get; set; }
        public MemberInfo MmbrInfo { get; set; }

        public Order_Info()
        {
        }
    }

         初步的思路是这样的,电商作为本地系统更新,淘宝和ERP的数据导入中间库,而后在中间库中形成自己的访问数据模式,而涉及到订单数据的对外接口,我们可以统一使用适配器模式,将淘宝的订单数据、ERP实体店的订单数据转化为本地电商的数据Model和业务实现类。

         由于适配器的实现,说到底就是若干各类组成的,为完成这样一个耦合度的设计,在这个实例中说白了就是我需要将TaoBao和ERP订单操作适用于Order,那么就需要针对TaoBao和ERP各写一个适配器类,那么实现起来不同的程序员或许有不同实现方式,我,所以,遇到这种统一规范的事情,第一想到的就是接口或抽象类。

    定义IOrderServiceAdapter接口,就此在系统架构中立一个永垂不朽的钉子,我的订单适配器都必须实现该接口,别的不认!

接口中定义了一个方法,返回类型为Order_Info为最终同电商的类型匹配,参数为一个类型Object,这里如果想继续复杂点,可以不用Object,使用泛型T实现。

代码实现:

public interface IOrderServiceAdapter
{
   Order_Info GetOrderInfoByOrderID(object obj, AdapterType at);
}

实现这个接口的就是为所有接入的订单信息,做准备的,我们这里比如的淘宝订单、ERP订单,若干天后,我们出现了京东的订单,再若干天后我们又出现了拍拍商城的订单,只要实现了这个接口,就能通自己电商系统中的订单信息进行适配。所以在系统中我加了第二个参数AdapterType,枚举类型,为就是分辨出不同来源的订单类型,进行转换,当然这里其实我们可以用工厂模式来进行处理,后续再细聊。

枚举类型实现代码:

    public enum AdapterType
    {
        Taobao_TransactionH = 0,
        ERPDD = 1
    }

适配器实现代码:

    public class OrderServiceAdapter : IOrderServiceAdapter
    {
        public virtual Order_Info GetOrderInfoByOrderID(object obj, AdapterType at)
        {
            Order_Info order = new Order_Info();
            switch (at)
            {
                case AdapterType.ERPDD:
                    ERPDD erp = obj as ERPDD;
                    order.OrderID = erp.DDID;
                    break;
                case AdapterType.Taobao_TransactionH:
                    Taobao_TransactionH th = obj as Taobao_TransactionH;
                    order.OrderID = th.TransHID;
                    break; ;
            }
            return order;
        }
    }

好,由此整个大的框架我们就确定了,运行代码:

    class Program
    {
        static void Main(string[] args)
        {
            Taobao_TransactionH tModel = new Taobao_TransactionH();
            tModel.TransHID = Guid.NewGuid().ToString() + "_TaoBao";
            ERPDD eModel = new ERPDD();
            eModel.DDID = Guid.NewGuid().ToString() + "_ERP";

            OrderServiceAdapter osAdapter = new OrderServiceAdapter();
            Order_Info orderH= osAdapter.GetOrderInfoByOrderID(tModel, AdapterType.Taobao_TransactionH);
            Order_Info orderE=osAdapter.GetOrderInfoByOrderID(eModel, AdapterType.ERPDD);

            Console.WriteLine(orderH.OrderID);
            Console.WriteLine(orderE.OrderID);
        }
    }

运行结果:

 附上我的源代码:https://files.cnblogs.com/aspnetdream/ModelPro_Adapter.rar

由此我们可以看出,将三个完全不搭的类型,搭到了一起,统一到了Order_Info的类型,我想上述的思想和思路可能,很多人一看都懂,也没有太多花哨的代码,但,我们确实使用到了设计模式,其实设计模式并没有那么高深,当然想用好,想用精可能高深的代码还真需要花功夫。

最后,在说说在《大话设计模式》中其实也指出来了,这个模式并不是事前模式,他更多的看做是一种修复模式,我们可以在实例中看到,其实,这个在愈合三个系统,如果是一般的设计一个全新的系统,大可不必使用着这个找兼容的模式,给一个新系统设计架构的时候,我们在设计之初就应该考虑兼容性,所以模式这篇中用扁鹊医病来形象的说明了这个问题,将病症防微杜渐才是真的高明的医生。

原文地址:https://www.cnblogs.com/aspnetdream/p/3061882.html