说到“Contract-First”,那么就首先要补充一下这一句:“Services share schema and contract, not class”。
Contract-First绝对是设计Service-Oriented系统中最重要的原则和理念之一。如果要动手做一个Service-Oriented的东东,首先要领会的关键之一,就是Contract-First。Service对外公开的接口,应当就是一个Contract,这个Contract的作用就像是它自己对外说明:“我能够提供哪些哪些服务,这些服务需要哪些哪些参数,会返回哪些哪些值...”如果服务间需要传递数据,那么也需要有Service和Client端公认的Contract,这个Contract用来说明:“我们要传递的这个数据,第一项是一个字符串用来包含姓名信息的,第二项是一个整数,包含了一个年龄信息...”由于Service间通常都会用SOAP包来交流,对于SOAP包的编码格式等信息,也需要用Contract来说明。
虽然已经有N多人在跟帖说“WebService != SOA”,但我还是要先拿WebService来说事儿。如何用Contract-First的概念来构建一个WebService呢?我们需要首先定义用来交换的数据的Contract(Data Contract),xsd就是用来定义数据Schema的。然后,我们再来定义Service和Client间进行通信的消息的Contract(Message Contract),别忘了Messsage-Based是Service-Oriented的基本特点之一。接着,根据这些由xsd来定义的Data Contract和Message Contract,生成我们的描述文件wsdl。wsdl描述了Service的接口和其用到的数据结构。从wsdl,我们就可以生成用来支持开发的实际的类代码文件了。
可以看出,Contract-First的设计理念和平时我们用来构建WebService的方式大相径庭。Contract-First的观点是需要首先确定Service与Client进行交互的各种Contract,数据的、消息的、接口的,而不是我们先把实际的类代码写出来,然后给它加上“[WebMethod]”,使其成为WebService接口。
使用Contract-First构建WebService的好处,就是Contract是独立的、可移植的、脱离于代码的。由于我们可以使用xsd来描述Contract,所以只需要和其他Service共享这些xsd描述文件,那么Service间就能共享这些Contract。我们不再需要让另外的Service去引用包含了Person实体对象的程序集,才能达到对方Service能交换Person数据的目的。相反,我们只需要共享出描述了Person结构的Data Contract给对方Service,即使对方Service可能是用Java实现的,它们也能根据这些Data Contract在它们的平台上生成实际的支持代码,并以符合Contract的方式来和本地的Service交换Person数据。
下面的截图出自WSCF:
定义的Data Contract:
<a href="http://blog.51cto.com/attachment/201003/121710451.gif" target="_blank"></a>
定义的Message Contract:
<a href="http://blog.51cto.com/attachment/201003/121716236.gif" target="_blank"></a>
Contract是由xsd文件来描述的:
<a href="http://blog.51cto.com/attachment/201003/121722374.gif" target="_blank"></a>
最后,由Contract,自动生成WSDL描述文件,然后从WSDL生成实际的支持代码:
<a href="http://blog.51cto.com/attachment/201003/121731587.gif" target="_blank"></a>
可以看到,上面的方式完全不同于传统的代码->加上[WebMethod]->自动由.asmx?wsdl生成wsdl等步骤。
下面是Indigo里面的一个Data Contract示例,Indigo里面使用[DataContractAttribute]来标识Data Contract:
[DataContract]
public class Person
{
[DataMember]
public String Name;
public DateTime Birthday;
}
下面就是一个Indigo Service接口示例,同样是使用了Attribute来标识Service Contract,和Service Contract中所包含的Service Operation:
[ServiceContract]
public interface IPersonService
[OperationContract]
Person GetPerson(String name);
void UpdatePerson(Person person);
public class PersonService : IPersonService
...
下篇Blog将会专门介绍Indigo。
本文转自 kaneb0y 51CTO博客,原文链接:http://blog.51cto.com/kaneboy/281329,如需转载请自行联系原作者