用消费者驱动的契约进行面向服务开发2010-04-11 infoq Ian Robinson 译者:徐涵向SOA过渡给软件开发生命周期带来了许多新的挑战:机构只有形成一种明确面向服务的开发能力,才能战胜这些挑战。SOA给开发带来的挑战面向服务(service orientation)不仅仅是采纳一种新的架构这么简单。若机构仅使其架构变得更加面向服务、而不对其开发技术作相应改变的话,那么SOA行动肯定要失败。在启动、构建及运营服务方面的一些挑战包括:在启动阶段,服务功能的描述必须能在多种场合下被重用:粒度既不能粗到仅在一种特定场合下能被重用,也不能细到要做大量补充工作方可在不同场合下被重用。在构建服务时,我们必须确保提供者与消费者可彼此独立地进行演化。如果一项服务功能的消费者们必须随提供者改变而改变,那么该服务就不是真正松耦合的。在运营服务时,我们需要理解各个服务之间的关系,以便我们可以诊断问题、评估服务可用性(availability)发生变化(常常是去除)时将产生的影响、并为各服务针对新的或变化的业务需求而演化设计计划。从整体资产的角度来看,各服务的具体开发生命周期必须彼此协调一致,且没有不恰当地将各方拴在一个一体的、极其缓慢的、最终无法实行的活动时间表之上。SOA给软件开发生命周期带来的挑战源于服务资产的联邦特性。有价值的业务成果不再是由那些“具有单向时间活动表,以及所有权、预算和运营边界都分散”彼此相隔的应用实现了;相反,它们是通过那些“拥有各自独特的服务开发生命周期的”服务之间的交互实现的。然而,协调好这些生命周期并不是一次搞定就完事了的。相反,正如我们将看到的,我们需要识别出一组代表着“对交付一个共同结果的承诺”的协作活动与制品(collaborative activities and artefacts)。这些活动与制品为时刻(若简单地看)将各条开发线联合起来提供了基础。用敏捷方法实现SOA,意味着及早交付高价值业务成果且常常需要频繁地发布版本。若机构试图采用这种方法,那只会进一步加剧开发挑战。尽管其名称如此,但许多人认为敏捷的软件交付方式对与SOA相关的机构敏捷效益是不利的。由于在一个服务间存在着很多已知关联的环境中发布新版本的服务会有运营风险,所以敏捷方法频繁发布版本这一做法常被免去。而且,虽然敏捷鼓励各方进行密切及时地协作,但这种活动难以跨越多个不同服务及其生命周期进行协调。联邦期望传统的烟囱式应用开发把彼此的交付线(delivery streams)排除在了业务所有权、预算及运营边界之外。面向服务的开发与传统的烟囱式应用开发的不同之处在于,它强调外部的依赖和约束,并把它们整合到了开发生命周期的每一步中去。这属于SOA治理领域:管理交付关联性,并围绕着关于“服务资产及该资产所支持的业务活动、流程及结果”的一个公共表示来安排交付线。SOA治理有赖于洞察与反馈——即对服务目录当前状态的洞察,以及关于演化中的服务提供者与消费者所产生影响的反馈。我们可以将联邦的期望和约束形成制品,这样便可增强洞察与反馈的能力。然后,这些制品就可以在一个特定服务开发线(service development stream)里的各阶段之间转移,以及/或者在不同开发线之间交换了。要掌握并交换期望与约束,一个实际的做法就是使用所谓的消费者驱动的契约(consumer-driven contracts)。消费者驱动的契约是存在紧密联系的服务契约三件套——提供者契约、消费者契约及消费者驱动的契约——中的一员,它从期望与约束的角度描述了服务提供者与服务消费者之间的关系:提供者契约(Provider contracts)——提供者契约是我们最为熟悉的一种的服务契约,参考 WSDL+XML Schema+WS-Policy。顾名思义,提供者契约是以提供者为中心的。提供者规定了它要提供什么;然后,各消费者便将自己绑定到这个一成不变的契约上。不论消费者实际需要多少功能,消费者接受了提供者契约,就将自己与该提供者的全体功能耦合起来了。消费者契约(Consumer contracts)——另一方面,消费者契约是对一个消费者的需求更为精确的描述。消费者契约描述了,在一次具体交互场合下,提供者功能中消费者需要的特定部分。消费者契约可被用来标注一个现有的提供者契约,另外消费者契约也有助于发现一个现今尚未规定的提供者契约。消费者驱动的契约(Consumer-driven contracts)——消费者驱动的契约描述的是服务提供者向其所有当前消费者承诺遵守的约束。一旦各消费者把自己的具体期望告知提供者,消费者驱动的契约就被创建了。在提供者方面创建的约束,确定了一个消费者驱动的契约。若提供者接受了一个消费者驱动的契约,那么它只需保证已有约束仍能得到满足,即可自行改进与修改其服务。

面向服务开发的生命周期