任务:组件规范(SOA)
本任务指定了实现设计子系统的服务组件的详细信息。
规程:分析和设计
用途

详细阐述一个或多个工具:设计子系统(已在任务:子系统设计(SOA)过程中描述)并提供详细的工件:服务组件设计。

关系
主要描述

基于 SOA 的解决方案中所使用的服务是通过工件:服务组件实现的,它们属于满足特定业务功能的子系统。 每个服务组件都有责任确保它将实现的服务的 QoS。 作为企业级的资产,每个服务组件都具有与自身关联的筹资、管理和维护方面的资格。基础结构管理必须到位以确保服务组件的可用性、负载均衡、安全性、性能,版本控制以及整体运行状况,它们将负责实施一组服务的功能并确保其服务质量。 功能组件和技术组件可以在多个服务组件中使用。

步骤
模型组件接口

组件(尤其是服务组件)不应直接提供操作,而应该使用接口来描述一组操作,然后再提供/实现此接口。在 RUP 中对此进行了概述,请参阅任务:子系统设计(SOA)任务:确定设计元素

示例

在“租车”示例中,我们已经确定了保留服务组件的需求(通过子系统分析)。 为了确保设计的可复用性和灵活性,我们还可以创建一个对应的保留接口,或使用服务规范(通过任务:服务规范)来描述至服务组件的接口。 组件将实现(以 UML 术语)每个提供的接口,并使用 UML 使用关系来表示它与其他组件的依赖关系(如下图中所示)。

请注意,为了清楚起见,我们已省略了接口本身的详细信息。

模型组件属性
在此步骤中,我们将定义每个服务组件的详细信息,包括属性、服务、策略以及规则。 记录服务组件规范的模板将包含以下属性:
  1. 属性
  2. 规则
  3. 变化
  4. 对 <其他组件> 的依赖
  5. 功能组件和技术组件的组合
  6. 提供的服务
  7. 所需的服务
模型组件事件和消息
在此活动中,我们将确定组件必须检测且一旦触发必须响应的事件。 还将指定入局和出局的组件消息。对于由对数据的更改而驱动的服务,必须采用数据中心视图,且必须确定和评估不处在基于服务的解决方案范围内的业务流程,以便生成事件并为面向服务的解决方案中的使用者服务提供数据。 例如,一个新的客户机可能由某个 ISV 软件包内的多个业务流程添加。在任何情况下,可能都不会为取决于特定业务流程环境的客户机捕获相同的数据。 需通过供应商服务发现新客户机的使用者服务必须能够处理新客户机服务的调用,不论该调用是哪个业务流程生成的。
模型组件内部结构

在此活动中,重点是创建至少一个显示每个服务组件的功能组件与技术组件之间关系的类图。 标准的 UML 建模适用于此阶段。 在模式的使用方面,最好以可扩展且开放更改的方式来构造结果对象图。如果期望进行大幅度的更改,建议在此阶段执行可变性分析

如先前的任务中所述,在对更改进行设计,或预计由于将来的业务更改而会对 IT 系统的设计和结构产生重大影响时,明智的做法是采用可变性分析技术。这些技术使用设计模式重构共同点并将变化外部化。可将早期发现的共同点和变化作为起点,然后通过使用公共设计模式(例如策略、状态[i]、规则对象 [ii] 和类型对象等)加以扩充。

在详细设计过程中进行的分析确定了共同点并重点构建可拔插变化,并包含了六大原则,这些原则有助于从较少的软件系统变化方面分离出变化,并隔离和封装这些变化:

  1. 将领域中不断变化的方面与不变的方面区分开来,并对变化的方面进行建模:对不断增加的变化进行确定、区分、封装和外部化。
  2. 为每个变化点创建类型层次结构。
  3. 向每种变化类型指定规则类型。
  4. 实施三个级别的抽象;使用聚集继承元方式。
  5. 从高于对象的复用级别开始,并在每个复用级别构建资产;在变化点周围构建小框架。通常而言,每个框架的类不应超过 7+-2 个。
  6. 每个复用元素都具有自己的行为。将行为外部化为可读取到应用程序中的可配置数据以允许软配线。

[i] Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides, Design Patterns, Addision-Wesley 1994.

[ii] Arsanjani, A., Rule Object: A Pattern Language for Flexible Modeling and Construction of Business Rules, Washington University Technical Report number:  wucs-00-29, Proceedings of the Pattern Languages of Program Design, 2000.

模型组件流

在此活动中,我们将确定服务组件中的内部控制流。这可以表示为序列或活动图。

ISV 考虑事项:将根据 ISV 软件包来确定包组件中的组件内部流是否显现和/或可配置。 如果 ISV 组件内的对象显现且可配置,则可以对它们进行调整和定制,以便更好地满足解决方案。 但是,必须意识到这样做所牵涉的潜在持续维护问题。 在许多情况下,既不可能,也无必要确定 ISV 软件包内的组件内部流。 在此例中,ISV 组件应视为“黑匣”,即只显现和实现记述的服务。

将组件分配到层

分层具有以下益处:

  • 层有助于为 IT 系统的可修改性和可移植性带来高质量的属性。对低层的更改如果不影响该层的接口,则无需更改高层。 例如,任何符合 J2EE™ 标准的 J2EE™ 兼容应用程序服务器都可以自由替换而无需更改应用程序级别的软件。 对于从低层获取设施的高层的更改,不会影响任何低层。 通常情况下,如果对分层软件系统进行的更改不影响接口,则这些更改限于单层。
  • 在构造系统时,体系结构起到蓝图的作用,而层则是该蓝图的一部分。通过了解软件所在的层,开发人员可了解在编码环境中可依赖什么服务。层可以为开发团队定义工作分配(虽然并非始终如此)。
  • 层是体系结构扮演的通信角色的一部分。在大型系统中,模块之间的依赖关系数量会迅速增长。将软件组织为具有接口的层是管理复杂性和将结构传达给开发人员的重要手段。
  • 层有助于体系结构扮演的分析角色。它们可用于分析对设计的更改所产生的影响。

分层可以是严格的,也可以是非严格的。严格的分层模式表示组件只能够使用同一层中的组件或其直接下层中的组件。 非严格的层模式表示组件可以使用同一层中的组件或任何下层中的组件。但是请注意,一般而言,不应允许组件使用其上层中的组件。如果组件依赖于高层中的组件,则很难在不更改低层组件的情况下替换高层组件。 关于更多信息(包括对层进行建模的技术),请参阅概念:解决方案分区

需注意的很重要的一点是软件层(layer)不同于层(tier)。向分布式环境中机器的分配、元素间的数据流以及通信信道的存在性和利用情况均倾向于以层(tier)图来表示,而如果以软件层(layer)图来表示,则可能无发辨别。 层(tier)图倾向于显示双向箭头,这些箭头表示特定种类的双向通信。 双向(对称)通信在层(layer)图中并不是一件好事。而且,向层分配组件是基于定义操作体系结构时拟定的安排规则,且是由系统的必需服务级别特性定义的。软件层(layer)图与层(tier)图的主要区别在于前者没有安排的概念,而后者则明确具有该概念。

分层通用规则

  • 提供不依赖于应用程序的业务功能的所有组件都可以放入同一层。 不依赖于应用程序的业务功能与“客户管理”和“产品管理”类似,适用于很多不同的应用程序。
  • 提供技术功能(如错误处理,认证、日志记录以及审计)的所有组件都可以放入另一(逻辑)层。 这些组件既是不依赖于业务的,也是不依赖于应用程序的。在某些情况下,技术组件与功能组件的接近性可能要求将它们放在公共层中。这些是体系结构决策,因此需要如此记录。
  • 中间件组件(如消息排队和相关的 DBMS 软件)位于另一层。这也称为“结构层”(Fabric)。

示例

以下是 SOA 的分层视图,显示了对应于解决方案中不同元素的典型层(并且实际上是推荐的层)。

现在在此分层模式中,很容易了解我们的组件将要所在的位置,可以将“租车”示例的相关组件放入“服务组件”层,如下所示。 请注意,我们希望在模型中采用严格的层,这样就可以利用 UML 组合在“服务组件”层中包含我们的组件,并且只使用委派端口显现服务组件的功能,其中,端口提供与服务组件本身相同的接口。

更多信息