在电子商务网站中,会设计与多家快递公司的接口交互。比如发送快递到某地,需要给各家快递公司API递交、取消、查询发货订单等等交互。

个人感觉设计模式中的适配器模式挺适合的,就设计了下,如下,其中考虑到有类适配器与对象适配器模式,这里主要用到的是对象适配器模。

其实这个例子用类适配器,就需要为每个快递公司去写类适配器,多少个快递公司,就有写多少个适配器,呵呵,觉得不可取。

所以,就设计了对象适配器来实现,使用抽象类来实现对多对象的实例。

业务主流程图如下:


 
下面示例中,使用YD,SF,ZJS(简写 韵达 顺丰 宅急送快递, lol)来代表快递公司具体操作类中的发送订单的操作方法,像取消订单、查询订单,都是类似的,这里就不多写了:

抽象类实现,提供抽象方法发送订单方法:

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Host.LogisticsService
{
public abstract class Adaptee
{
public abstract bool SendOrder(); // 抽象方法 用作统一多类库中的方法
}
}

SF、YD、ZJS等物流公司操作具体类,我这里直接返回,具体实现省略:

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Host.LogisticsService
{
public class SF : Adaptee
{
public override bool SendOrder()
{
return true;
}
}
}
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Host.LogisticsService
{
public class YD : Adaptee
{
public override bool SendOrder()
{
return true;
}
}
}
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Host.LogisticsService
{
public class ZJS : Adaptee // 继承抽象类
{
/// <summary>
/// 重写实现抽象类中方法
/// </summary>
/// <returns></returns>
public override bool SendOrder()
{
return true;
}
}
}

接口:

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Host.LogisticsService
{
public interface IDelivery
{
bool Send();
}
}

DeliveryAdapter 适配器来操作:

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Host.LogisticsService
{
public class DeliveryAdapter : IDelivery //继承具体实现最上层方法的接口
{
private Adaptee _adaptee;
/// <summary>
/// 构造函数去实例了继承了抽象类中的类的具体对象
/// </summary>
/// <param name="adaptee"></param>
public DeliveryAdapter(Adaptee adaptee) //构造函数去实例了继承了抽象类中的类的具体对象
{
_adaptee = adaptee;
}

/// <summary>
/// 实现了继承了抽象类中的具体对象的抽象类的重写方法
/// </summary>
/// <returns></returns>
public bool Send()
{
return _adaptee.SendOrder();
}
}
}

各类和接口依赖项关系图如下:


其中Service 可以忽略的,我用来做其他事的,Program.cs 用来测试的,TestObjectAdapter()是测试方法。

View Code
        /// <summary>
/// 测试对象适配器
/// </summary>
private static void TestObjectAdapter()
{
IDelivery zjs = new DeliveryAdapter(new ZJS());
zjs.Send();

IDelivery yd = new DeliveryAdapter(new YD());
yd.Send();

IDelivery sf = new DeliveryAdapter(new SF());
sf.Send();
}

这样,就完成了多种快递公司的接口适配。

最终实现了: 将一个类的接口,转换成客户期望的另一个类的接口。适配器让原本接口不兼容的类可以合作无间。