http://www.cnblogs.com/goody9807/archive/2007/06/05/772107.html

什么是契约先行(Contract-First)?

如果说一个新的软件开发模型会影响甚至改变软件开发过程,那么这样的改变对于开发人员而言,无疑是最具有深远意义的。多年以来,大多分布式应用程序的开发人员都习惯关注对象和从头开始编写一大堆的代码。然而,在面向服务(Service-Oriented)的时间,一切都将改变。从面向过程到面向对象,再到基于组件的开发(Component Based Development),软件开发领域经历着一次又一次的变革,而Web Services的盛行则将软件方法学的革新再一次的推到了浪尖口,一切都处在变化的焦点之中。

关于SOA(面向服务的体系架构)不论在工业界还是学术界,都有了太多的讨论,有称之为“后OO时代的软件体系架构”,也有人认为SOA代表未来的主流方向,但是目前并不适合大规模的进入工业应用,也有太多的专家和学者在SOA和Web Services的关系上前扯不清。纷争也罢,潮流也罢,有一点我们不得不承认,随着Web Services渐渐成为分布式应用特别是异构系统整合的标准协议,这种“服务自治,共享协定但不共享实现”的软件构造方式得到了越来越多开发人员的追捧,契约先行也正是源于此。

开发人员在定义Web Services服务契约的时候有两种选择,一种方式就是在代码实现之前首先完成WSDL的定义,我们在这里就称这种开发方式为“契约先行(Contract-First)”,另外一种方式就是首先完成代码编写,然后依赖于底层基础架构(如ASP.NET)产生契约,这种方式我们称为“代码先行”。这两种方式各有优缺点,但是大多的开发都是采用“代码先行”,例如首先利用Visual Studio.NET编写Web Services的实现,然后通过ASP.NET提供的Web Services机制生成相关的WSDL,相信大多开发人员是如此完成工作的。

“契约先行”强制要求你使用能够理解WSDL的共享语言工作,然后直接使用WSDL对于开发人员而言是一件很棘手也很不爽的事情,因为目前没有特别好的工具提供对WSDL开发的支持,传统的面向对象技术也无法做到直接完成从对象到WSDL的映射工作。利用“代码先行”则能够从某种程度上来帮助“契约先行”开发中存在的问题,正如上文提到的利用ASP.NET的ASMX(相信大家知道这是什么类型的文件)运行时产生WSDL,另外有一种做法就是利用Xml系列化产生相关的属性。但是基于模式(Schema)的开发方法在目前中是最优的,因为你可以直接定义服务消息和数据,这样做的结果是可以帮助您的服务具有更好的交互性和独立于本地代码类。但是Schema-Based的契约先行开发方式最大的挑战也再此:如何找到好的工具来帮助开发人员和架构师在设计阶段完成简化模式设计。

WSCF

而thinktecture提供的WSCF(Web Services Contract-First)正是一个这样简化开发人员契约设计工作的工具,这个工具提供了很多功能和特性来帮助开发人员将精力集中在契约先行开发中最重要的步骤:消息和操作设计。WSCF作为一个插件和Visual Studio 2003进行了非常好的集成,因此开发人员和架构师能够在不离开习惯的IDE时继续工作。

如何使用WSCF

在基于模式的契约先行开发中,不同于传统的编程语言开发,其大致可以分解成五个步骤:

1.       数据建模

在这个步骤中定义数据结构,以保证通过Web Services接口中传递的消息能够被正确交换。

2.       消息建模

确定需要进行交换的消息,这样的XML Schema可以通过XMLSpy或者VS.NET自带的XSD进行编辑。

3.       操作和接口建模

定义希望提供给Web Services消费者提供的方法操作

4.       生成代码骨架

根据上述定义的数据、消息和操作及其接口产生平台依赖的代码(如C#或者Java)。

5.       迭代契约式设计和代码生成

重复上述步骤

应用程序场景

如下我们就通过一个简单的例子展示如何使用WSCF进行契约先行开发

工程组织

首先我们创建一个空的应用解决方案,同时添加三个工程到新建的解决方案中,如下表格显示了各个工程的用途

工程名

工程类型

介绍

ContractMetadata

C#空白项目

包含数据、消息和接口的原数据定义

RestaurantService

C#空白Web项目

餐馆服务Web Services实现

RestaurantClient

C#控制台项目

餐馆服务Web Services客户端实现

消息和数据建模

添加完毕上述的工程之后,就需要我们开始定义契约,正如上述所述,我们首要的工作是创建一个用来描述Restautant数据的XML架构,同时命名为RestautantData.xsd,具体如下图所示

图1:数据格式

与此同时,我们需要定义交换数据的消息

(图2)为此我们增加了名为RestaurantMessages.xsd的XML架构文件,为了能够引用RestaurantData.XSD的数据,我们需要手工在XSD文件中加入图3所示的代码

图2:消息定义

图3:Import语法

接口契约建模

在文章的开头提到过,接口协定表现为WSDL文档,显而易见的,没有哪个家伙愿意首先编写WSDL,如果让你去读懂WSDL规范,然后一点点的编写,那将是一个无比痛苦的过程,到目前为止,市面上也没有特别好的工具可以直接支持WSDL文档的编辑,我们需要一个从更高抽象角度的工具来界定我们的接口协定。

WSCF提供了一个WSDL生成向导,就如同ASMX运行时那样,尽其可能的对开发人员和架构是隐藏WSDL规范的技术细节,下表显示了目前WSCF对操作引用的字符串模式支持,简单的说,WSCF能够根据XSD提供的消息定义自动推断一些操作。

输入消息

输出消息

推断操作

XYZ

XYZResponse

XYZ

XYZRequest

XYZResponse

XYZ

ZYZRequestMessage

XYZResponseMessage

XYZ

最后WSCF支持一些简单的WSDL迭代操作,也就意味着您可以利用生成——察看——修改——生成WSDL文档,让我们来看看如何利用WSCF的向导生成WSDL文档。

图4:利用WSCF生成WSDL文档

通过点击在RestaurantMessage.xsd的右键菜单我们可以看到如图4的界面,启动向导之后按照向导的要求一步一步完成操作,这个时候就产生了我们需要的WSDL文档,这个也是契约先行开发的最关键步骤,如图5所示,我们得到了命名为“RestaurantService.wsdl”的文档,那么剩下的工作就是开始产生代码了。

图五:ContractMedadata的文件布局

从契约产生代码

在这里我们仅讨论生成.NET平台下面的代码,对于其他平台如Java,都提供了从WSDL到Java代码的转换工作,有兴趣的读者可以参阅Eclipse或者其他Java DE的相关文档。如图6所示,WSCF支持生成客户端和服务器

的代码

我们可以根据需要生成相关的程序代码,然后实际业务情况实现具体业务细节。生成的部分代码如下所示

public class RestaurantInfo

{

private string name;

public string Name

{

get

{

return this.name;

}

set

{

this.name = value;

}

}

}

其他

同时WSCF提供了一个命令行工具”wscf.exe”,它是一个基于命令行的代码生成引擎,可以通过wscf.exe –help察看详细参数使用信息。

小结

通过如上的演示我们可以看到如何利用XSD和WSCF结合实现契约先行开发,当然,不要指望通过一个工具就能够替你完成所有的工作,WSCF只是在WSDL的生成和代码生成上提供了简化的使用方式,至于如何在”代码先行”和“契约先行”之中作出选择,就依赖于你的具体应用了,一般来说,在如下场景中优先考虑“契约先行”的开发方式

1)  客户端和服务器段都还没有实现代码,并且契约变动的情况是存在的

2)  客户端和服务器段异构的,简单的说客户端和服务器段可能采用不同的平台实现,如客户端使用Java,服务器端使用.NET

3)  系统互操作的场景比较复杂

利用WSCF进行契约先行的Web Services开发的更多相关文章

  1. 利用PHP SOAP扩展实现简单Web Services

    原文:利用PHP SOAP扩展实现简单Web Services WebServices能干什么? WebServices 可以将应用程序转换为网络应用程序. 通过使用 WebServices,您的应用 ...

  2. 跟我一起学WCF(3)——利用Web Services开发分布式应用

    一.引言 在前面文章中分别介绍了MSMQ和.NET Remoting技术,今天继续分享.NET 平台下另一种分布式技术——Web Services 二.Web Services 详细介绍 2.1 We ...

  3. 利用Web Services开发分布式应用

    一.引言 在前面文章中分别介绍了MSMQ和.NET Remoting技术,今天继续分享.NET 平台下另一种分布式技术——Web Services 二.Web Services 详细介绍 2.1 We ...

  4. JAX-RS介绍——Java API forRESTful WebServices,JAX-RS的目标是Web Services开发(这与HTML Web应用不同)而Spring MVC的目标则是Web应用开发

    JAX-RS Java API forRESTful WebServices旨在定义一个统一的规范,使得 Java 程序员可以使用一套固定的接口来开发 REST 应用,避免了依赖于第三方框架.是一个J ...

  5. 使用 Spring 3 来创建 RESTful Web Services

    来源于:https://www.ibm.com/developerworks/cn/web/wa-spring3webserv/ 在 Java™ 中,您可以使用以下几种方法来创建 RESTful We ...

  6. 使用 Spring 3 来创建 RESTful Web Services(转)

    使用 Spring 3 来创建 RESTful Web Services 在 Java™ 中,您可以使用以下几种方法来创建 RESTful Web Service:使用 JSR 311(311)及其参 ...

  7. Spring 3 来创建 RESTful Web Services

    Spring 3 创建 RESTful Web Services 在 Java™ 中,您可以使用以下几种方法来创建 RESTful Web Service:使用 JSR 311(311)及其参考实现 ...

  8. 在 IBM RAD 平台上基于 JAX-WS 开发 Web Services服务器端,客户端

    原文地址:https://www.ibm.com/developerworks/cn/websphere/library/techarticles/1305_jiangpl_rad/1305_jian ...

  9. Java Web Services面试

    Q. 应用集成方式有哪些? A. 应用可以采用以下方式集成: 1. 共享数据库 2. 批量文件传输 3. 远程过程调用(RPC) 4. 通过消息中间件来交换异步信息(MOM) Q. 应用集成可以采用的 ...

随机推荐

  1. Windows Phone 8 下载文件进度

    后台代码: public partial class MainPage : PhoneApplicationPage { private long siz; private long speed; p ...

  2. 将IList转换为List

     简单点说,IList<T>直接转换为List<T>可以不用考虑.IList<T>可以用至少2种方式简单的复制成List<T>:1.IList<T ...

  3. Css-自适应高度修复(高度随内容而自动撑高)

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  4. Beta版本冲刺———第一天

    会议照片: 项目燃尽图: 1.项目进展: 昨天的困难:对2048项目中方块颜色的调整 今天解决的进度:调整了方块的颜色,原来用UIColor.(颜色名)color颜色效果不是很好,现在改用了RGB调色 ...

  5. 揭秘PHP匿名函数

    揭秘PHP匿名函数 定义:匿名函数就是没有名字的函数. 有2种形式的匿名函数: 形式1:将一个匿名函数"赋值"给一个变量--此时该变量就代表该匿名函数了! 形式2: 是直接将一个匿 ...

  6. MyBatis学习--SqlMapConfig.xml配置文件

    简介 SqlMapConfig.xml是MyBatis的全局配置文件,在前面的文章中我们可以看出,在SqlMapConfig.xml主要是配置了数据源.事务和映射文件,其实在SqlMapConfig. ...

  7. virtio 半虚拟化驱动

    半虚拟化驱动 5.1.1 virtio概述 KVM是必须使用硬件虚拟化辅助技术(如Intel VT-x.AMD-V)的hypervisor,在CPU运行效率方面有硬件支持,其效率是比较高的:在有Int ...

  8. vmware 在NAT模式下连接上外网

    文章: http://www.2cto.com/os/201504/389011.html

  9. E(X+Y), E(XY), D(X + Y)

    \(X, Y\)为两个随机变量, \(p_X(x), p_Y(y)\)分别为\(X, Y\)的概率密度/质量函数, \(p(x, y)\)为它们的联合概率密度. \(E(X + Y) = E(X) + ...

  10. 状态压缩codeforces 11 D

    n个点m条边 m条边 求有几个环; #pragma comment(linker, "/STACK:102400000,102400000") #include <iostr ...