【IT168 技术文章】
本文的内容
在本文中,我们将第 3 篇文章中创建的服务提供者集合在一起,以另一个服务提供者的方法来使用它们的功能。也就是说,我们将从其他服务的合成要素中创建一个新的服务。这一技术能够被递归使用任意次,越过任何一个关注集和任何一个抽象层。然而,有可能存在许多体系结构的约束,对服务操作的粒度、安全性和执行关注、数据交换量、以及有可能约束什么服务是由什么合成要素提供的写级通讯协议和绑定问题。这些问题决定解决方案的体系结构,并且不在本系列这些文章的讨论范围之内。请参见 Design an SOA solution using a reference architecture 获得关于这一重要课题的更多细节。
如同本系列中的所有文章一样,我们将使用现有的 IBM? Rational? 和 IBM? WebSphere? 工具来建造解决方案,并且将它们链接到一起,从而我们能够检验该解决方案是否符合需求和更加有效的管理变化。表1总结了我们开发例子将使用的全部过程,以及我们所使用的工具。
表1. 开发过程角色、任务和工具
角色 任务 工具
业务执行官 传达业务目标 IBM? Rational? RequisitePro?
业务分析师 分析业务需求 IBM? WebSphere? Business Modeler
软件架构师 设计解决方案的架构 IBM Rational Software Architect
Web 服务开发人员 执行该解决方案 IBM? Rational? Application Developer 和 WebSphere Integration Developer
服务实现回顾
我们首先回顾在前面的文章中被执行的服务提供者。图1显示了 Invoicer 服务提供者。

图 1. Invoicer 服务提供者
Invoicer 服务提供者为计算定购单的最初成本提供了 InvoicingProtocol,然后当运送信息得知以后重新定义这一价格。定购单的总价取决于产品是在哪里生产的,以及它们是从哪里运送的。最初成本的计算可能被用来检验消费者有足够的信用或者仍然想要定购产品。在实现定购之前完成这一检验操作是最好的。
图2显示了 Productions 服务提供者。

图 2. Production 服务拓扑结构
Productions 服务提供者提供 Scheduling 服务,决定产品在哪里被生产,以及如何何时被生产。这一信息能够被用来创建运送时间表,这个表在处理定购单时使用。
图3显示了 Shipper 服务提供者。

图 3. Shipper 服务提供者
Shipper 服务提供者提供 ShippingService 服务,将产品运送到消费者来完成定购。该服务需要 ScheduleProcessing 接口来请求消费者处理完成的时间表。
服务合成
现在,服务已全部由一些提供者提供,我们已经准备好将这些提供者集合起来使用,实现最初的业务需求。这种集合根据业务需求来合成和设计服务,为 Purchasing 服务提供一种方法。我们将创建一个 OrderProcessor 合成要素,为处理定购单提供一个购买服务。这个服务提供者要求服务被 InvoicingService、Scheduling 和 ShippingService 服务规范定义。我们将创建一个 OrderProcessing 合成要素,它集合了 Invoicer、Productions 和 Shipper 合成要素的实例,以及 OrderProcessor 合成要素,从而执行处理定购单的操作。
Order Processor 服务提供者
定购单处理服务由 Purchasing 服务规范指定(请参见图4),该规范包括如下功能(或者操作):
+ processPurchaseOrder (customerInfor : Customer, purchaseOrder : PurchaseOrder) : Invoice
这一服务将由 OrderProcessor 服务提供者提供。OrderProcessor 是一个合成要素,它通过将其他服务提供者(根据需求契约设计的)连接在一起来提供一个服务。也就是说被提供的服务方法的某些方面被设计用来以某种方式使用其他服务提供者。这一合成要素通过它的购买服务端口提供 Purchasing 接口。所有的消费者接口都是通过这个端口的,从而将消费者客户端从同合成要素同其他服务消费者或者提供者的相互作用中分割出来。这样做限制了模型中的耦合性,随着市场和服务消费者和提供者的变化能够更容易的做出改变。
图 4. Purchasing 服务规范
OrderProcessor 合成要素的组织展现在图5中所示的 Project Explorer 视图中。
图 5. 定购管理业务功能区域(包)
OrderProcessor 服务提供者包含在 org::ordermanagement 包中,它用于组织同定购管理相关的服务。定购管理包也包含相关的服务接口、服务消费者和服务提供者。
图6中显示的 OrderProcessor 图表提供了 OrderProcessor 服务者及其提供的和要求的服务的一个外部视图。(要求的服务有时被称作请求,以便同功能需要相区分。)外部的或者叫做“黑盒”视图是呈现给服务提供者的消费者查看的。稍后将显示的合成要素的内部结构提供了一个支持合成要素的执行设计结构的一个内部的或者叫做“白盒”的视图。
图 6. OrderProcessor 服务提供者
外部视图不是一个从执行中分离出来的规范;它仅仅是合成要素某些方面的视图。如果架构师或者开发人员希望完全的将服务提供者的规范从它的可能执行中分离出来,就将使用到规范合成要素。规范合成要素定义了一个服务消费者和服务提供者之间的契约,它从特定的提供者执行中减弱了它们。规范合成要素能够被许多具体的合成要素识别出来,这些要素以一种识别契约的方式提供服务,并且提供服务的可接受的质量。请参见“SOA 建模: 第二部分 服务规范”获得更多细节。
OrderProcessor 服务提供者要素十分简单和稳定,在这个例子中,架构师和开发人员决定不使用服务规范。结果是,使用 OrderProcessor 合成要素的任何服务消费者都将同这个特定的执行相联系。这是不是一个充分的设计取决于有多少服务将被使用,以及随着时间的推移它们将发生多大程度的改变。只有解决方案架构师能够决定一个特定的系统能够容忍什么程度的耦合性。
OrderProcessor 合成要素也拥有反映有其他服务提供者(货品计价、时间表、运送)提供的需要请求的服务端口。这些服务提供者提供了 OrderProcessor 合成要素用来执行其被提供的服务操作的那些服务。
每一个服务交互作用点都涉及到一个简单协议,该协议影响被提供的和被要求的接口。例如,货品计价交互作用点要求 Invoicing 接口启动价格计算器,并且发送运送价格。然而,它可能会花费一些时间来计算运送价格,所以 OrderProcessor 通过其货品计价端口来提供 InvoiceProcessing 接口,从而使得货品计价服务提供者能够在其准备好时发送一张发货单。
Order Processor 执行设计模型
我们现在完成了服务模型的架构,并且在服务提供者的外部视图中捕获到它。下一步就是为 OrderProcessor 合成要素所提供的 processPurchaseOrder 服务操作提供一种方法。这种方法必须遵循任何一个已经完成的服务契约或者已经实现的服务规范,也要遵循那些操作已经被定义的服务规范。
内部结构
OrderProcessor 服务提供者通过它的购买服务端口提供了一个简单的服务规范 Purchasing。这个服务规范指定了一个简单的操作 processPurchaseOrder。服务提供者必须为它所提供的全部服务操作提供一些方法。在这个例子中,我们使用 Activity 作为 processPurchaseOrder 服务操作的方法。有关的细节被显示在提供服务的 OrderProcessor 合成要素的内部结构中。OrderProcessor 内部结构在图表、接口、类和活动中被捕获,如图7中的 Project Explorer 视图和图8中的复合结构图表所示。
图 7. OrderProcessor 服务提供者的组织

Project Explorer 视图显示了 OrderProcessor 提供者各个部分的列表,以及每一个被提供的操作的方法(行为)。在这个例子中所使用的约定是,使用一个和合成要素名称一致的类图表,并且在包含该合成要素的包中,显示它的外部视图。这就是图6和图7中所显示的图表。同合成要素具有同样名称并且被包含在合成要素中的复合结构图表,提供了服务提供者结构的内部视图。这个图表直接位于图7中的 OrderProcessor 服务提供者的下面。这些约定能够更好的协调服务参与者的外部和内部视图,并且如同合成要素一样仔细研究图表。
OrderProcessor 复合结构图表如图8所示,提供了一个服务提供者的内部结构的总体视图。再一次显示了合成要素的合成静态结构的各个部分(端口和属性)。
图 8: OrderProcessor 服务提供者的内部结构

OrderProcessor 合成要素的内部视图很简单。它由用于被提供的和被要求的接口的服务端口、加之许多其他保持服务提供者状态的属性共同合成。属性 ID 被用来识别服务提供者的实例。这个属性将被用来动态的关联消费者和提供者的交互作用。属性 schedule 和 shippingInfo 是在 processPurchaseOrder 服务操作的执行中被使用的信息。
被提供的服务操作的方法
由服务提供者所提供的每一项服务操作必须通过以下两种方式之一被实现:
Behavior (Activity、Interaction、StateMachine 或者 OpaqueBehavior),它是操作的方法;
属于合成要素的一个 Activity 中的 AcceptEventAction (异步调用)或者 AcceptCallAction (同步需求或者回复调用)。
这允许一个单一的 Activity 拥有多于一个的并发进入点,并且它符合 Business Process Execution Language (BPEL) 中的多重接收活动。这些 AcceptEventActions 通常被用来处理回叫信号,从其他异步的 CallOperationActions 中返回信息。
OrderProcessor 合成要素包含两种服务实现风格的例子。processPurchaseOrder 操作拥有一个同样名字的方法活动。这一活动,如图9所示,是提供服务操作的服务提供者所拥有的一种行为。
图 9: processPurchaseOrder 服务操作实现
这个图表同用于相同行为的 WebSphere Business Modeler 图表非常符合。InvoiceProcessing 和 ScheduleProcessing 服务操作通过过程中的 processInvoice 和 processSchedule 接收事件行动被实现。请注意接口中的相应操作被指示为触发器操作,它指出响应 AcceptCallActions 的能力(类似于接收和 AcceptEventActions,此处触发器是一个 SignalEvent)。关键字触发器并不是 UML 2 的一部分,它只是用来强调这些操作是如何实现的。
注释:
除非 processPurchaseOrder 活动正在运行,并且控制流程已经到达两个接收呼叫行动,否则这些操作将不会被接收。这指示出一个操作的执行能够决定其他操作何时将被响应。
实现服务契约
OrderProcessor 合成要素至此已经完成。但是还有两件事没有做:
首先,我们需要将 OrderProcessor 服务提供者同对其需求进行建模的业务过程相结合。
其次,我们需要创建一个子系统,将能够提供 OrderProcessor 需求接口的服务提供者和适当的服务端口连接起来。
这将导致一个能够运行的可配置的子系统。这一小节将处理链接 SOA 解决方案和业务需求的问题。下一小节将介绍可配置的子系统。
本小节中的操作不会对 OrderProcessor 合成要素如何转变为一个 SOA 执行产生任何改变。将合成要素链接到服务契约,只是描述合成要素如何完成那些契约所指定的需求。这并不影响服务提供者的执行或者它将如何被转变为一个 SOA 解决方案。然而,联接较之依赖要复杂得多。它特定的显示服务提供者的各个部分在服务需求契约中扮演什么角色,以及合成元素完成业务的约束。这提供了更加丰富的可追溯性,对有细密纹理的变化管理的支持,以及使用模型验证解决方案确实满足它们的需求的能力。
图10使用一个服务契约显示了 OrderProcessor 服务提供者的需求,该服务契约提供了一张由业务分析师创建的业务过程的角色中心视图。一个协作使用被添加到 OrderProcessor 服务提供者中,指出它所完成的服务契约。
图 10: 实现服务契约
图10中被称作契约的的协作使用,是图11中所显示的 Purchase Order Process 服务协作的一个实例。这指定了 OrderProcessor 服务提供者完成 Purchase Order Process 业务需求。角色绑定指示出服务提供者的哪一个部分在服务契约中扮演哪一个角色。例如,货品计价端口扮演货品计价角色,购买端口扮演 orderProcessor 角色。
这些角色绑定和下一小节中所描述的服务信道连接器并不相关。服务信道连接器被用来连接子系统中的消费者请求和提供者服务。角色绑定指定了该部分在服务契约中扮演什么角色。角色绑定既可以是严格的也可以使松散的。严格的契约完成意味着各个部分必须同它们所绑定到的角色类型一致。松散的契约完成意味着各个部分将会根据架构师的要求扮演那些角色,但是模型验证并不验证角色和部分功能。也就是说,或许因为业务服务契约不完全,或者只有业务需求的概略信息。
图 11: Service Requirements 契约
显示 SOA 解决方案如何完成业务需求要花费额外的工作来指定契约和角色绑定,但是它提供了一个管理变化的有利条件。模型查询可能被用来决定哪一个服务提供者完成什么业务需求。需求中的任何改变将可能导致服务协作中的其中一个角色的变化。建模器于是能够直接定位到扮演那些角色的部分,决定代表那些可能需要改变的角色的服务规范如何处理需求中的变化。模型验证也能够被用来决定某些角色是否被改变,以及在 SOA 解决方案中扮演该角色的各个部分不再有能力执行角色的所有责任。这较之用例实现的不具备支持语义或者松散语义的老套依赖要强大得多。正是这种类型的形式,可验证的 SOA 解决方案和业务需求之间的连接器(确保解决方案是业务相关的,满足需求,并且是敏捷的解决方案),才能够便于适应改变。
组装 OrderProcessing 子系统
在我们的 SOA 解决方案中,最后要做的就是创建一个 OrderProcessing 子系统,它使用我们一直执行的服务提供者将各部分装配到一个可配置的解决方案之中。
这个子系统如图12所示,它反映了一个将 OrderProcessor 服务提供者同其他提供其需求服务的服务提供者连接起来的可配置的合成要素。这个子系统是提供所有配置和运行 OrderProcessor 服务的必要信息的合成要素的一个集合。
图 12: 将各部分组装到一个可配置的子系统之中

OrderProcessing 子系统包括 OrderProcessor、Invoicer、Productions 和 Shipper 服务提供者合成要素的实例。销售者合成要素的货品计价服务同 Invoicer 合成要素的货品计价服务相连接。这是一个有效的连接,因为 OrderProcessor 合成要素的货品计价服务的服务规范,正是 Invoicer 提供者的货品计价服务的变形。OrderProcessor 合成要素要求 Invoicing 接口,它是由 Invoicer 服务提供者所提供的。它还为 Invoicer 提供了 InvoiceProcessing 接口,接收更新的货品计价。
连接服务(服务规范的实例)意味着参与者同意根据服务规范相互作用连接器。也就是说,它们同意遵守被要求的协议。服务规范定义了协议中被连接的参与者所扮演的角色。orderProcessor 消费者的货品计价端口和货品计价提供者的货品计价端口之间的服务信道连接器拥有一个契约(行为),这个行为是 InvoicingService 服务规范的 InvoicingService 行为。连接器的名称根据约定被设置为其契约的名称。任何经过这个连接器的交互作用都被要求遵守契约或者协议。这些连接器将服务架构中的使用依赖形式化了。
请注意,生产者和销售者部分之间的连接器没有契约。这是因为在 Scheduling 服务接口中没有协议,所以该连接器不需要契约。
其他消费者和提供者以相似的方式被连接起来。连接的服务能够提供不同的绑定风格。服务相互作用点之间的服务信道能够指定实际使用的绑定风格。
OrderProcessing 子系统现在已经完成,并且做好被配置的准备。它已经指定了服务提供者完全执行 processPurchaseOrder 服务所必须的所有被需要的实例。在它被配置以后,其他服务消费者能够绑定到销售者 OrderProcessor 合成要素的购买服务,并且调用该服务操作。
总结和下一步工作的展望
至此,我们已经完成了服务、消费者和提供者达到业务目标所必须的识别、规范和实现。结果得到一个和技术无关的但是完全的架构服务解决方案的设计模型。
要实际运行这一解决方案,我们需要创建一个同服务模型中被捕获的架构设计决定相一致的平台执行。我们能够将该模型作为向导,通过手工来创建这个解决方案。但是这样做非常冗杂、易出错、费时间、并且需要一个高水平的开发人员确保架构决定能够正确的被执行。当然可以通过手工来创建解决方案,并且将该模型作为向导也是非常有帮助的。但是,一个完全的、正式的、经过验证的模型才能使我们有机会进行模型驱动的开发(MDD),从模型中创建一个解决方案的骨干,然后在特定平台编程环境中完成细节的编码。这正是下一篇,也就是本系列最后一篇文章:“SOA 建模: 第五部分 服务执行”中的内容。在那篇文章中,我们使用 Rational Software Architect UML-to-SOA 转换特性,创建一个能够直接在 WebSphere Integration Developer 中执行、测试和配置的完整的 Web 服务解决方案。
参考资料
学习
您可以参阅本文在 develperWorks 全球网站上的 英文原文。
由 Jim Amsden 撰写的 SOA 建模: 第 1 部分 服务识别,即本系列五部曲中的开篇之作,其内容关于基于面向服务的架构(SOA)的软件开发。(IBM? developerWorks?,2007年10月)
由 Jim Amsden 撰写的 SOA 建模: 第 2 部分 服务规范,对 SOA 解决方案每一个服务的规范进行详细的建模。(IBM? developerWorks?,2007年10月)
由 Jim Amsden 撰写的 SOA 建模: 第 3 部分 服务实现,介绍基于 SOA 的 Web 服务如何被实际实现。(IBM? developerWorks?,2007年10月)
由 Ali Arsanjani 撰写的 基于服务的建模和架构: 如何为你的 SOA 鉴别、指定和实现服务,关于 IBM Global Business Services 的面向服务的建模和架构(SOMA)的方法。(IBM? developerWorks?,2004 年 11 月)
IBM Business service modeling,是由 Jim Amsden 撰写的一篇 developerWorks 文章(2005 年 12 月),文章描述了业务过程建模和服务建模之间的关系,获得两者的利益。
“使用模型驱动开发和基于模式的工程来设计 SOA,第 2 部分: 基于模式的工程”,IBM develperWorks 指南系列四部曲的第二部分(2007 年)。
“使用 Rational Software Architect 设计 SOA 服务”,IBM developerWorks 指南系列四部曲(2006 年 - 2007 年)。
“用 Rational Software Architect 建立面向服务的体系结构(Service-Oriented Architecture)的模型,第 3 部分: 外部系统建模”,IBM developerWorks 指南系列六部曲的第 3 部分(2007年)。
为面向服务的解决方案建模,是 Simon Johnston 的一篇著名文章,文章描述了服务建模驱动面向软件服务的 UML Profile 以及面向 SOA 插件程序的 RUP 的开发方法。(developerWorks,2005 年 7 月)
用于软件服务的 UML 2.0 Profile,也是由 Simon Johnston 撰写的(developerWorks,2005 年 7 月),文章描述了面向软件服务的 UML Profile,即一种允许对服务、面向服务的体系架构(SOA)、以及面向服务的解决方案进行建模的 UML 2.0 规范。该规范现在已经在 IBM Rational Software Architect 中被执行。
由 Donald Ferguson 和 Marcia Stockton 撰写的 用于实现 Web 服务的 SOA 编程模型,第 1 部分: IBM SOA 编程模型简介 (developerWorks,2005年6月),描述了面向服务的架构(SOA)的 IBM 编程模型,它使得非编程人员能够创建和复用 IT 资产。该模型包括组件类型、配线、模板、应用程序适配器、统一的数据表示、和 Enterprise Service Bus (ESB)。这篇文章是关于 IBM SOA 编程模型和选择、开发、配置和推荐程序模型元素需求的内容的系列文章的开篇之作。
服务数据对象(Service Data Objects) 单一化并且统一化了应用程序访问和操作不同种类数据源的方法。
请参见 Business Process Execution Language for Web Services 来了解更多关于 BPEL 1.1 规范的知识。
订阅 developerWorks Rational zone newsletter。时刻关注 developerWorks Rational 的内容。每隔一个星期,您都将收到 Rational Software Delivery Platform 最新的技术资源和非常好的实践的更新。
浏览 技术书店 来获得更多技术主题的书籍。
获得产品和技术
下载面向 SOMA 方法的 Rational Unified Process 插件程序:IBM RUP for Service-Oriented Modeling and Architecture。您必须具备 IBM Rational Method Composer 来安装该插件程序。
下载 RUP plug-in for SOA,使用 IBM Software Services Profile 对面向服务的 Rational Unified Process 插件程序进行建模。
IBM SOA Sandbox IBM SOA Sandbox 提供了完全版本软件试验和 “在线试用” 主机环境(在此您能够探索指南并且获得架构的指导)的一种混合。
下载试用版本:IBM Rational Software Architect V7。
下载 IBM 产品评估版本,并且从 DB2?,Lotus?,Rational?,Tivoli? 和 WebSphere? 中获得应用程序开发工具和中间件产品。
讨论
查看 developerWorks 博客,并且参与到 developerWorks 社区 当中。
Rational Software Architect、Data Architect、Software Modeler、Application Developer 和 Web Developer 论坛:提出关于 Rational Software Architect 的问题。