技术开发 频道

浅析Web Service适配器

服务方法兼容性适配

1、准备 

    还是上面的那个示例,如果消费者Web Service需要的不是一整票报价,而是报价单中某一票商品的内容,那么调用时他除了id、company两个参数外,还需要提供对应QuoteItem的productId,因此需要进行服务方法的适配。


图8:服务方法兼容性适配

    参考上例和上图,定义作为Adaptee的生产者Web Service和作为客户程序的消费者 Web Service。测试报价单数据如下:

//XML
<?xml version="1.0" encoding="UTF-8"?>
<Quote Company="VisionTask" Id="Quote 2007-07-18"
xsi:schemaLocation="http://www.visionlogic.com/trade quote.xsd"
xmlns="http://www.visionlogic.com/trade"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<QuoteItem ProductId="19" QuantitiveInStock="1750" Price="3.14"/>
<QuoteItem ProductId="312" QuantitiveInStock="10" Price="3000"/>
</Quote>

2、根据消费者Web Service的需要,定义对应的Service Adapter

//C# ITarget
using System.Xml;
namespace VisionTask.Training.ServicePattern.UtilityService.MethodAdapter
{
/// <summary>
/// 消费者Web Service 需要的接口。
/// </summary>
public interface ITarget
{
XmlNode GetItem(string company, string id, string productId);
}
}
//C# QuoteServiceMethodAdapter
using System.Xml;
using VisionTask.Training.ServicePattern.Common.Xml;
using VisionTask.Training.ServicePattern.ServiceAdapter;
namespace VisionTask.Training.ServicePattern.UtilityService.MethodAdapter
{
public class QuoteServiceMethodAdapter : IServiceAdapter, ITarget
{
/// <summary>
/// 实现一般性IServiceAdapter 的要求。
/// </summary>
public virtual string Name { get { return "ServiceMethod"; } }

/// <summary>
/// 实现消费者 Web Service 需要的接口。
/// </summary>
public XmlNode GetItem(string company, string id, string productId)
{
XmlDocument doc = (new ProducerServiceM()).GetQuote(company, id);
if ((doc == null) || (!doc.HasChildNodes)) return null;
string xPath = "/Quote/QuoteItem[@ProductId=" + productId + "]";
System.Diagnostics.Trace.WriteLine(xPath);
XmlNode node = doc.SelectSingleNode(xPath);
return node;
}
}
}

3、借助抽象的 Service Adapter,实现消费者 Web Service

//C#
using System;
using System.Xml;
using System.Web.Services;
using System.Web.Services.Protocols;
namespace VisionTask.Training.ServicePattern.UtilityService.MethodAdapter
{
/// <summary>
/// 客户Web Service。
/// 它继续封装对外的服务,使用时可以根据他获得某公司提供的报价单中,
/// 具体某项商品的价格。
/// </summary>
[WebService(Namespace = "http://www.visionlogic.com/trade")]
public class ConsumerServiceM : System.Web.Services.WebService
{
[WebMethod]
public double GetPrice(string company, string id, string productId)
{
ITarget target = new QuoteServiceMethodAdapter();
XmlNode node = target.GetItem(company, id, productId);
if (node == null) throw new NullReferenceException();
return Convert.ToDouble(node.Attributes["Price"].Value);
}
}
}

其他说明 

    对于第三种“封装性适配”则是上述两种方式的组合: 

    •数据的转换。 
    •方法的适配。 
    •在Service Adapter中嵌入额外的逻辑。 
    •而双向适配则是双方各自定义自己的适配器。

0
相关文章