技术开发 频道

SOA术语:分析和设计

服务实现

    服务实现旨在对如何实现服务进行设计。这一设计已经达到最为详细的程度(仅次于代码级)。它的目的并不是实现(构造)服务,而是在设计级描述如何实现服务,至于实现(构造)服务,将在第 3 部分予以介绍。服务实现是由软件架构师和设计师来完成的。

    在规范和实现之间有一道明显的鸿沟。您可以用一个简单的方法看出它们的区别:如果说服务规范解决的是是什么的问题,服务实现介绍的就是怎样做。

设计模型

    由 RUP SOMA 定义的设计模型,是服务实现的核心输出工作产品。它描述了 SOA 的实现,是对实现(包括代码)的抽象。服务实现的输出将被输入到服务的正式实现之中。

服务组件

    您应当关注的主要设计模型组件是设计组件,它表示的是一个或多个服务规范是如何实现的,还描述了如何处理所有的功能性/非功能性需求,以及结构和行为规范。

    在服务实现期间会创建大量的新类,对服务组件和服务进行细化。此外还会定义这些类的结构和行为。

    正如先前所说的那样,服务实现应当大量使用设计模式(如委托模式、独立模式和工厂模式),这些模式一般是在服务实现期间被应用到各个类的。

WSDL 和 XML 模式

    在实现期间,您将针对各种技术作出决策。事实证明,Web 服务对于 SOA 而言是一个可靠的平台。MDD 工具(如 IBM Rational Software Architect)可以根据服务模型为服务提供者生成 Web 服务描述语言 (WSDL),以及相关的 XML 模式文件 (.xsd),后者会定义在服务提供者和使用者之间流动的消息。无疑,WSDL 和 XML 模式既可以是服务实现的输出,也可以是实际的服务实现过程的初始输出之一。

QoS 和服务分区

    选择采用什么技术,对服务质量有巨大的影响。某些技术可能不支持您的某些需求。在可靠的消息传递或性能(如吞吐量)方面就有这样一个例子。对于传统(非面向服务的)设计而言,您最好将各个供选择的技术映射到分区。而对于 SOA,在服务实现期间,可能需要对在服务规范期间定义的服务分区进行修改,以便让特定的技术来处理相关的服务策略(访问途径、安全、性能等等)。例如,您可以想一想某些性能需求和互操作性需求,前者要求在内存中处理事务,而后者可能会使用 SOAP 和 Web 服务,或在某些情况下改用本地调用。

    在您完成了服务设计之后,下一个步骤就是根据这一设计实现(构造)服务,这将在本系列的下一部分中介绍。

服务设计原则

    这一部分将列出您在设计 SOA 解决方案时必须牢记的四项服务设计原则。不过请注意,这并不是一份官方的正式列表,而且也并不全面,其中一些概念来自于其他范例,如面向对象。这些原则在面向服务的解决方案设计中是十分重要的。

重用

    在设计服务时,请把重用这一原则随时记在心中。通常,在设计时,特定的服务使用者会有特定的要求。不过,如果您想从 SOA 中获益,您会希望那些需求略有不同的其他使用者会重用自己设计的服务。而在您创建设计时,并不知道这些使用者,也不知道它们有什么需求,因此这并不是一项轻松的任务。

    下面是您可以考虑的事项:

  • 根据业务域(而不是技术)为服务及其操作提供一个有意义的描述性名称。
  • 提供完整的、可由人工阅读或计算机处理的规范,并将其公布给服务注册中心,使服务可以被发现(详细信息,请参阅本系列后续的部分)。
  • 各个使用场景的服务质量与初始场景不同,例如,如果服务被频繁使用,需求和工作负载提高,可以制订相应的计划。
  • 是否有可能对服务提供的初始功能(是根据初始需求集提供的)进行扩展,以便完善服务。
  • 是否有可能在多种不同的平台上实现某个服务规范。

松散耦合

    耦合是指实体或系统彼此间的依存程度。在 SOA 的上下文中,您可以考虑服务规范与它的提供者或实现之间的耦合,或服务提供者与服务使用者间的耦合。如要支持 SOA 应有的灵活性,必须采用松散耦合。

    服务提供者无需了解服务使用者的某个特定实例,反之亦然。如果要替换某个服务提供者或服务的实现,必须保证这样做对使用者造成的影响可忽略不计,或不会对其造成干扰。

    如果要帮助实现松散耦合,请考虑下列事项:

  • 将服务规范(本文中所述的服务和模型)与服务实现分离开来。正如第 2 部分有关 MDD 的那一节所描述的那样,对于服务而言,拥有完整的规范是十分重要的,规范不会依赖于某个特定的实现。而且,服务契约应处于规范级别(而非实现级别)。
  • 使用工具,以一种人机可读的标准格式(如 WSDL 和 WS-Policy)描述服务规范,以使代码生成器能帮助您实现服务( 本系列的第 4 部分将提供这一方面的详细信息)。
  • 当开发服务使用者的代码时,请记住,可能存在服务中间层或其他提供者,请不要对某个提供者的实例的任何信息进行硬编码。

 

无状态性

    事务状态意味着服务必须具有关于某些发生的事件的信息,这些事件是一个在服务提供者和服务使用者各自的特定实例间长期运行的事务的一部分。例如,如果服务操作已被调用,或在调用某个操作前需要先调用另一个操作,在这两种情况下调用服务操作的结果是不同的。虽然在基于组件的开发中可以找到事务状态的身影,但对于 SOA 来说,事务状态却是应该避免的。

    数据(信息)状态意味着需要对数据实例的状态进行管理。某些服务通常需要管理数据的状态。以保险业中的索赔服务为例。该服务必须管理索赔实例的状态,因为多个用户会通过不同的业务事务访问这些实例。注意,保持状态不变的服务通常是原子(细粒度服务)。如要处理状态需求,您应依靠一些在实现中运用的基础技术,如 Java™ 平台、使用状态会话 Bean 的 Enterprise Edition (Java EE) 等等。

粒度

    对于面向服务的设计,您可以对粒度进行考虑,如服务提供者级或服务规范级的粒度(对于前者而言,要考虑应提供多少服务)。服务规范是一个针对服务操作的逻辑分组。在此处,逻辑表示它在业务方面的合理性。例如,在保险领域中,一个索赔处理接口将提供使用索赔处理的场景中所需的所有操作。这在 IT 实现方面也是合理的。例如,服务中所有被标识出的操作都可以通过同一种开发迭代实现。

    在设计服务操作时,请考虑协作、使用场景,以及在服务提供者和使用者之间流动的消息的数目和大小。粗粒度的操作可以提供更高的业务价值,而且使对实现的修改变得更容易了。粗粒度操作的参数(使用消息作为输入、输出和故障参数)出错率较低。不过,使用细粒度的参数(而不是消息)通常具有更好的描述性。例如,如果某个操作服务签名为 determineEligibility(application: ApplicationMessage),则您需要查看 ApplicationMessage 的定义。如果签名为 determineEligibility(customer : Customer, product : Product, date : Date, amount : Amount),则该签名的描述性更好。此外,CustomerProduct 参数类型(举例来说)可以在其他操作中重用,这与 ApplicationMessage 不同。

    对于服务粒度,请务必记住,服务是可组合的。这涉及到重用和在现有功能基础上提供新功能的能力。某一粒度级别的一组服务可以通过编排,形成另一个具有较粗粒度的服务。您可以想想这个例子:多个服务提供各种业务任务,然后将这些业务任务排成序列(一个业务流程),以提供另一个服务。

    最终,如果要在设计决策中确定服务粒度,应当在性能(如在高效实现的前提下,用于交换的消息的大小和数目)和重用的可能之间作出折衷。而且,一个典型的 SOA 会同时包括细粒度(原子服务)和粗粒度(组合服务)两种服务。

0
相关文章