服务集成中关注点分离的调查
摘要
大型软件系统中不断变化的业务流程、异构数据源的集成以及对遗留服务集成的需求,推动了软件设计朝着可重用、平台无关、可通过 Web 访问的微服务方向发展。这些独立可部署的服务提供了以机器可读格式进行数据检索和数据操作的接口。尽管这种方法从服务集成的角度来看具有诸多优势,旨在将数据操作与业务处理分离,但标准方法通过接口提供的结构语义和约束却十分有限。这导致在集成组件中出现大量信息重复以及重复决策,显著增加了开发和维护工作量。集成组件的可操作性变得高度依赖于与底层服务的交互,而底层服务本身可能由其他服务组合而成。这种依赖性在所生成和消费信息的结构语义方面尤为明显,交互双方必须保持这些语义的一致性。本文从关注点分离的角度对服务集成进行了调查。为了降低集成组件侧的耦合度和信息重复,本文建议在服务交互中引入带有附加信息的多通信通道,从而增强集成组件推导服务所需信息的结构语义、约束或业务规则的能力。最后,我们从开发和维护的角度探讨了这一新方法的影响。
关键词 :Web服务 · 服务集成 · Aspect-Oriented编程
1 引言
大型系统的软件设计,集成来自不同异构数据源的功能,并提供去中心化治理,利用可重用、可独立替换、可扩展和可部署的微服务[13]。此类服务提供可组合功能,解决了单体设计的缺点。[13]它们提供平台无关性,支持使用标准机器可读格式的不同组件之间的互操作[1]交互。这些服务强调明确定义的接口和网络上的可用性,并具备位置透明性。
强调服务接口使得服务提供者之间的轻松替换成为可能,从而降低了集成组件(或一般对等方)与服务之间的耦合。一种独立的、可自主部署并集成服务的组件在本文中称为集成组件(IC)。IC‐服务交互可以进一步由多个提供者进行中介,以支持服务可用性、可扩展性和性能。服务可以递归地集成其他服务,使此类服务组合对IC透明。市场变化、创新和/或业务需求的演进使得IC能够方便地使用新型服务,或在现有服务基础设施之上应用新的业务流程。同时,这种设计特别是在早期开发阶段,可能比以代码为中心的单体设计需要更高的投资[1],,但为服务未来的广泛重用打开了可能性。因此从长期来看,总体成本有望降低。IC对其底层服务中的故障、缺陷或性能瓶颈较为脆弱。此外,通信标准格式带来了额外的性能开销,涉及信息在机器可读格式与内部平台特定格式之间的序列化和反序列化。
基于现有技术构建的服务提供以特定结构格式化的信息,集成电路(ICs)必须严格遵循该结构。当前的基于标准的方法提供了内部结构的一些数据值和语义,但这不足以在集成电路端自动推导出其内部结构。例如,属性数据类型有限,且缺少其约束或验证规则。此外,无法自动确定服务所消费信息的预期结构语义。从设计角度而言,集成电路必须为服务提供的信息实现适当的内部结构表示。这些通常为数据传输对象(DTO)[10],或映射结构。这些组件为原生平台定义了结构,尽管这实际上是一种重复声明,因为该结构已存在于 Web服务端并由其共同定义。这给集成电路带来了承诺。每当服务信息定义的结构发生变更时,其集成电路必须同步反映该变更,从而导致维护困难,因为目前尚无机制可防止此类不一致性。
当考虑多个相互通信的IC或中间件都处理相同的信息表示、相同的约束、验证规则等情况时,情况会变得更糟。维护变得复杂,关联脆弱性增加。不同的个人可能在异构位置管理特定的服务或IC,并遵循不同的演进和变更。服务通常不了解其ICs,因此其内部变更可能导致灾难性后果。由于这些困难,如今常见的情况是
实践1 在数据发生结构变化时,保持现有服务不变。不是扩展特定服务,而是创建一个带有变更的副本。因此,这两个服务同时运行。这种方法自然不具备可扩展性2因为必须监控多个此类服务的运营和备份,从而推高了运营成本。
本文从关注点分离的角度探讨服务集成。其动机是减少维护工作量,并减轻服务结构表示、约束、验证或业务规则变更对集成电路(ICs)造成的影响。集成电路(ICs)由此能够适应上述服务关注点的变更。
传统方法使用单通道进行信息通信以传递给ICs。如前所述,只能从中提取有限的结构化信息。例如,考虑一个以XML或JSON格式生成信息的Web服务。这些格式携带数据值,并通过属性名称部分描述数据结构,但在类型、约束等方面存在缺失。因此必须存在集成组件内部表示来提供缺失的信息,从而引入了重复定义。
一种关注点分离方法提出了不同的通信形式。它提供了新的元信息,可用于在运行时推导集成电路的内部结构表示。这些元信息涉及不同的关注点。除了完整的数据结构信息外,通信通道还可考虑输入验证规则、用户上下文和业务规则。若将这些关注点通过单一通信通道提供,会导致效率低下,因为某些关注点的变更频率高于其他关注点。因此,我们建议采用多通信通道,以避免重复并支持在通信层面实现关注点分离。这扩展了集成电路侧的关注点重用,并提升了缓存能力[6]。所有新的关注点均以机器可读格式提供。ICs 能够基于服务提供的信息,在运行时推导出内部结构表示、约束、验证和业务规则。后续的服务变更将由 ICs 及其所有通信后继者自动采纳,有助于避免一致性错误。
本文的其余部分组织如下。第2节提供背景信息。第3节提供了服务集成中关注点分离分析的详细信息。第4节详细介绍了关注点分离设计。相关工作在第2至第4节中均有提及。第5节对论文进行总结。
2 背景
Web服务生成和消费数据。一个Web服务是唯一能够访问数据源的组件,也是唯一能够持久化或提供数据的组件。通常,此类服务将数据持久化到关系数据库中,尽管其设计很可能采用面向对象编程(OOP)。即使是采用非传统风格设计的遗留系统服务,也可以扩展以提供Web服务接口[1]。此类服务通过机器可读格式(如XML或JSON)进行通信。
从 Java 企业版(Java EE)平台 [9] 可以看出当代面向对象设计(OOP design)的趋势。该平台为持久化提供了对象关系映射(ORM)的标准,称为 Java 持久化 API(JPA),并支持输入验证(Bean Validation),甚至支持将对象表示的数据序列化/反序列化为 JSON 或 XML 格式 3 以及逆向操作。
在 Java EE 平台中,服务通过称为实体的类来表示其数据模型,这些实体相互关联,并通过 JPA 描述符扩展以实现 ORM,同时通过 Bean验证描述符实现输入验证。服务可以通过引用特定的实体及其属性,在数据模型之上实施业务规则。如 [3,10], 所述,目前尚缺乏定义业务规则的标准或普遍接受的方法。一种可能的方式是使用面向对象编程(OOP)[2] 来定义此类规则;然而,这会导致在不同系统模块或层次中对规则的大量重复定义 [3],,从而增加维护工作量。其他方法建议使用基于领域特定语言(DSLs)的框架来描述规则,例如 Drools [16] 或 MPS [17]。这些方法将规则定义隔离,并在整个系统中强制应用这些规则。
Web服务向其他集成电路隐藏其内部细节,尽管它提供或消费的信息结构受其实体及其数据结构的影响。有时,服务通过使用数据传输对象(DTO)进行间接操作来聚合实体或过滤其属性 [10]。随后,这些实体或数据传输对象决定了所需格式(XML/JSON)。在考虑生成的格式时,它包含与特定数据实例相关的信息,以及与数据结构相关的信息,因为每个数据值都与其属性一起提供。因此,该产物包含有限的结构信息;然而,它并不提供预期的属性数据类型、约束等。
集成电路必须遵循服务所期望的数据结构。集成电路的内部数据表示与服务类似,可以使用为此目的设计和编译的数据传输对象,或基于服务提供的信息生成的映射数据结构。映射结构看似更灵活,但在向服务提交数据时,无法提供类型安全或对正确数据结构、属性类型、约束等的保证。从服务数据消费的角度来看,映射结构可能显得不切实际,因为其内部结构接受任何输入,但服务可能会由于类型错误而拒绝该信息。
数据传输对象(DTO)和映射结构的属性都必须与运行时服务表示保持一致,以避免不一致性错误和服务提交被拒绝。问题在于服务和集成电路(IC)是具有不同演化时间跨度的独立组件。因此,每当服务端的数据表示发生变更时,
集成电路表示必须相应地进行变更。集成电路的数据传输对象属性重述存在紧密耦合问题,并且无法适应服务的变更,其结构在编译时即已确定。目前缺乏一种机制来指示或防止由于服务内部结构变更而导致的一致性错误。
重述问题不仅限于数据表示;输入验证也存在类似问题。出于性能和可用性的考虑,我们在集成电路(IC)上执行输入验证,以避免产生通信和服务端处理的开销,但为此需要在IC上手动实现输入验证。由于相同的验证规则在各层中被重复声明,这会对开发和维护工作产生负面影响。此外,当IC集成多个服务时,可能需要在IC层面就应用业务规则,这同样会导致这些规则在各层之间复制。
上下文感知加剧了这种情况[4]。例如,考虑被授权访问不同数据属性的多种用户角色。从服务自治的角度来看[1], ,这应在服务层面实现,但由于可用性角度,集成电路侧也不能忽略这一问题[14]。上下文感知比单纯的安全性更为复杂[4]。用户可能来自不同的地理位置,在不同的时间,使用各种设备,这些都可能影响所提供的数据、数据表示、其结构、验证规则或业务规则。大量决策可能在不同层级重复出现,并与其他应用程序关注点交织在一起[6]。
当前的Web服务系统设计支持服务重用、组合、分布、复制和跨平台兼容性。然而,它未能有效处理集成组件开发或服务演进。正如我们所展示的,许多关注点在不同层级被考虑,但缺乏一种跨层级共享关注点的机制。本文提出了一种应用于ICs之间通信的关注点分离方法。其优势在于,服务层面考虑的关注点可以被其他ICs重用,从而简化服务演进,并提高ICs对服务变更的适应能力。传统方法中上下文感知会导致关注点纠缠,加剧复杂性以及开发和维护工作量。所提出的方法通过多通道实现关注点分发,相较于单通道通信能更有效地处理上下文感知。多通道关注点分发扩展了重用[6]并支持缓存能力。
3 服务中关注点分离的分析与讨论
我们发现了传统服务集成设计中的若干问题。无论内部服务设计如何,与其他 ICs的交互仅能提供有关服务关注点的有限信息。它主要关注数据值的交互。数据表示必须在ICs和服务之间进行结构上的关联。验证规则和约束必须在IC端进行复制。
当服务未公开其源代码时,集成电路设计只能考虑服务文档,以在其设计中应用服务业务规则,从而提高可用性。即使提供了代码,规则推导也可能非常困难,因为一个服务可能将业务规则纠缠在面向对象设计中[3],而另一个服务可能使用 Drools,另一个使用MPS。所有后续变更都必须再次与ICs相关联,这使得全局业务规则的维护变得困难。运行时上下文(如安全性、时间、集成电路位置等)可能会影响所生成或消费的数据。从关注点的角度来看,我们考虑以下要素:
每个使用服务并希望处理其数据值的IC,都会重新声明数据结构表示,很可能还包括其验证规则。IC可能需要重新声明业务规则,甚至集成上下文。除了数据值之外,这给开发、服务演进和维护带来了显著的责任和负担。上述服务元素的微小变更都可能导致集成该服务的多个IC出现不一致性,从而需要手动进行变更传播。变更传播的问题在于,服务通常不知道其消费者,或对消费者的控制能力极为有限。
很自然的问题是,是否存在一种方法可以降低集成电路与服务之间在数据结构表示或其他关注点上的耦合。为此,集成电路端的数据结构表示不能在编译/部署时静态确定,而应通过一个独立的通信通道提供,并在运行时确定其结构表示。
假设一种通信形式,其中集成电路(IC)请求数据结构表示,然后将数据值映射到该表示上。其后果是什么?首先,集成电路必须在运行时构造该表示,这要么需要元编程 [7] ,要么需要使用映射数据结构。由于结构在编译时无法确定,字段引用在集成电路范围内可能会失去类型安全 [4],这可能对编程风格产生负面影响。另一方面,由于服务在集成电路部署后可能随时发生变更,类型安全仅有助于集成电路的初始设计。其次,运行时按需表示推导可确保与服务的一致性。因此,集成电路能够反映服务结构的后续变更,从而改善维护和演进。第三,由于通信开销和元编程可能导致性能下降。另一方面,数据结构表示请求可以与数据值请求并发发出 [6]。同时,数据结构表示的推导过程可以考虑类似HTTP [6],的缓存机制,其中集成电路请求一个
特定表示版本,并在服务端发生变更之前重用所派生的结构。
通过提议的设计,服务通过独立通信通道提供数据结构表示。同样的方法也可应用于数据输入验证。尽管此关注点与之前的关注点有许多相似之处,但当我们考虑Java EE中的Bean验证标准时,它甚至是数据模型(其扩展)的一部分[6]。这表明有可能将该关注点集成到用于数据结构表示的通道中。
服务业务规则在ICs执行期间可能是未知的。这些规则可以被记录下来,但除非重新表述这些规则,否则ICs无法将其与服务分离使用。如果能够以机器可读格式将规则提供给IC,那么IC便可利用这些知识来提升可用性或性能。例如,考虑一种情况:根据当前乘客占用情况限制特定航班的飞机选择。如果IC知晓此类限制,它就可以避免向服务发送额外请求或提交被拒绝的尝试。另一种情况是,服务业务规则在客户端被解释,从而触发网页浏览器JavaScript执行,在提交前验证约束条件。为了通过特殊的通信渠道向ICs提供业务规则,服务必须以一种既能支持规则评估又能转换为适合传输格式的方式捕获这些规则。例如,一个暴露了独立解析器、内部表示和执行功能的DSL解决方案就适用于此目的。从ICs的角度来看,业务规则定义通常通过名称引用数据结构表示及其属性,这引入了耦合,并限制了IC适应服务变更的灵活性。所提出的IC运行时推导数据结构表示的方法可能会妨碍在IC端定义业务规则。
上下文感知可能是软件系统能力的下一个演进步骤 [5]。如今,生产系统很少涉及上下文感知功能 [4] ,即使涉及,也仅限于有限范围 [6], ,例如交互式控制台,这是由于开发和维护工作量增加所致 [4]。例如,人机交互展示了现有的上下文感知原型 [14] 和简洁的功能;然而这些原型由于性能要求 [5] 或巨大的开发工作量 [4] 而缺乏生产经验。一项调查 [4] 表明,上下文感知背后的复杂性与关注点分离不佳有关。那些无法从系统其余部分清晰分解的关注点被称为横切关注点 [12]。传统编程语言无法有效处理横切关注点,并导致代码纠缠。
最新技术建议通过生成式编程(GP) [8] 或面向切面编程 [12] 来解决这些问题。不幸的是,程序结构和整体设计必须做出改变。
特定表示版本,并在服务端发生变更之前重用所派生的结构。
通过提议的设计,服务通过独立通信通道提供数据结构表示。同样的方法也可应用于数据输入验证。尽管此关注点与之前的关注点有许多相似之处,但当我们考虑Java EE中的Bean验证标准时,它甚至是数据模型(其扩展)的一部分[6]。这表明有可能将该关注点集成到用于数据结构表示的通道中。
服务业务规则在ICs执行期间可能是未知的。这些规则可以被记录下来,但除非重新表述这些规则,否则ICs无法将其与服务分离使用。如果能够以机器可读格式将规则提供给IC,那么IC便可利用这些知识来提升可用性或性能。例如,考虑一种情况:根据当前乘客占用情况限制特定航班的飞机选择。如果IC知晓此类限制,它就可以避免向服务发送额外请求或提交被拒绝的尝试。另一种情况是,服务业务规则在客户端被解释,从而触发网页浏览器JavaScript执行,在提交前验证约束条件。为了通过特殊的通信渠道向ICs提供业务规则,服务必须以一种既能支持规则评估又能转换为适合传输格式的方式捕获这些规则。例如,一个暴露了独立解析器、内部表示和执行功能的DSL解决方案就适用于此目的。从ICs的角度来看,业务规则定义通常通过名称引用数据结构表示及其属性,这引入了耦合,并限制了IC适应服务变更的灵活性。所提出的IC运行时推导数据结构表示的方法可能会妨碍在IC端定义业务规则。
上下文感知可能是软件系统能力的下一个演进步骤 [5]。如今,生产系统很少涉及上下文感知功能 [4] ,即使涉及,也仅限于有限范围 [6], ,例如交互式控制台,这是由于开发和维护工作量增加所致 [4]。例如,人机交互展示了现有的上下文感知原型 [14] 和简洁的功能;然而这些原型由于性能要求 [5] 或巨大的开发工作量 [4] 而缺乏生产经验。一项调查 [4] 表明,上下文感知背后的复杂性与关注点分离不佳有关。那些无法从系统其余部分清晰分解的关注点被称为横切关注点 [12]。传统编程语言无法有效处理横切关注点,并导致代码纠缠。
最新技术建议通过生成式编程(GP) [8] 或面向切面编程 [12] 来解决这些问题。不幸的是,程序结构和整体设计必须做出改变。
通用编程(GP)建议从传统组件和集成模型、领域特定语言(DSLs)描述或其他问题描述格式来设计应用程序。它将上述所有内容作为输入,然后基于配置脚本和模板,生成来自这些输入的各种组合。结果可能产生大量组合,随后进行编译。当某些输入在其组合上呈现指数级依赖时,就会带来困难。[4] 在这种情况下,生成的结果变得不切实际。另一个缺陷是该方法针对编译时产品推导。此外,执行使用的是生成的代码,这使得调试更加复杂。
AOP 提议通过两个构建模块来设计应用程序。基础功能通过传统组件及其扩展来实现,这些扩展是可分离关注点,甚至是通过另一个称为切面的构建模块捕获的横切关注点。切面可以使用领域特定语言(DSL)或相同的编程语言。切面提供了一种机制,用于将特定关注点从基础程序中分离出来。组件与切面之间的连接方式是 AOP 的主要手段。基础组件程序被转换为连接点表示 [12]。连接点可以是方法名、方法调用、程序中的位置,或是带有注解扩展的方法。它指示了切面可以扩展程序执行的位置。这种连接点表示是程序或特定子系统的简化骨架。切面具有由连接点构成的条件,用于指示其何时以及在何种上下文中被激活。该条件可使用任何逻辑或算术运算符以泛化条件。切面的集成可以在编译时或运行时 [4], 进行,因此只有由给定上下文激活的切面才会应用于程序执行。组件与切面的集成由切面织入器完成,这是一种类似于编译器 [12] 或渲染器 [4] 的工具。由于该方法可在运行时应用,生成的结果不会受到指数级关注点依赖的影响,因为只有上下文选定的关注点会应用于给定请求,尽管与调试相关的复杂性仍然存在。
因此,在追求高效设计的同时扩展服务的上下文感知能力,应考虑通过切面将基本功能与上下文扩展分离开来。尽管上下文与其他服务关注点不同,但我们可能并不希望将上下文作为独立通信通道提供给ICs。相反,我们可能认为上下文是请求服务的IC相关的或由其提供的内容(例如,请求参数、位置、访问权限),或是服务端在运行时推导出的内容(资源使用、时间)。因此,上下文可能会影响所提供的结果。
以集成电路(IC)的授权级别较低时请求服务为例,该服务应仅消耗或生成部分数据值,或向该IC提供有限范围的数据表示。或者,考虑集成电路( ICs)请求与地理位置相关的敏感个人信息的情况。一个IC可能接收到包含 country、state以及自定义日期格式的信息,而另一个IC仅接收到country和通用日期格式的信息。
4 设计与关注点分离方法的参考文献
为了分离前一节中提到的关注点,并将它们流式传输到独立的通信通道中,我们必须能够在服务端解释关注点描述。然而,我们应该避免重新发明现有解决方案,也不应期望行业在传统开发或程序员态度上做出重大改变。出于这些原因,我们可能倾向于避免采用模型驱动开发(MDD)[4]下一个选择是在更高层次的抽象级别上为服务描述设计自定义DSL [15],但这种方法与模型驱动开发(MDD)并无太大区别,因为开发者必须学习一门新语言并改变设计抽象。相反,应尽量减少对开发人员的影响,以便于采用并顺利过渡到生产开发。
一种可能性是使用基于元编程的代码检查机制。这些方法允许重用现有代码以实现转换,对于我们而言,即数据结构表示。例如,[11]在 MetaWidget框架中使用了这种方法,从数据模型生成用户界面(UI)。类似地,[4]使用元编程来生成连接点表示[12],以便后续用于基于AOP的转换。应用代码检查机制不会显著影响服务开发视角,因为其使用是透明的。
同样,在考虑现有的验证或ORM标准时,代码检查可以推导出验证规则和约束,从而进一步扩展连接点表示。其他数据结构表示扩展也可以以相同方式考虑(访问、呈现扩展 [6], 等)。
此时,开发影响并不涉及重大变更,即使该服务为关注点提供了通信通道。AspectFaces框架[4]提供了一个示例代码检查工具。[6]展示了其在用户界面推导中用于分离关注点交付的应用。为了在服务级别应用该方法,框架的切面织入器指向应用程序数据模型,从中推导出连接点表示,该表示可双向转换为XML/JSON格式。一个集成电路(IC)从接收到的连接点模型推导出服务内部的平台相关数据结构表示,并填入提供的数据值。[5,6]展示了该方法在移动设备、独立客户端以及Web客户端(Google Web Toolkit、AngularJS、 HTML5)的用户界面推导中的使用,证明了关注点交付的平台无关性。服务数据结构表示的变更会被所有跨平台推导出的用户界面所采纳。此外,[6]详细说明了可应用的缓存选项和性能优化措施。例如,如前所述,对不同通道(数据值和连接点表示)的请求可以并发执行。连接点表示可以被缓存并重用,同时通过类似HTTP的版本控制机制实现失效管理。
在集成电路(IC)中的使用会影响开发视角。集成电路通常旨在集成多个服务,并处理多种数据结构表示形式。其内部集成电路结构表示是一个具有定义名称的代理,其属性(如字段)在运行时获取,这会降低开发时的类型安全性。这是为适应服务结构变化能力所付出的权衡代价。优势在于,对数据值的验证和约束执行是代理的一部分,可在集成电路端进行。当集成电路应用业务规则并进行业务处理时,通过属性名称将显式引用绑定到代理上。这限制了集成电路对数据结构变更的适应性,因为服务中属性名称的更改不会更新集成电路的命名绑定。在集成电路端使用领域特定语言(DSLs)进行业务规则定义和执行不受此方法的影响,因为此类领域特定语言(DSL)本身类型安全性就有限。集成电路可执行业务处理,并将代理转发给其他集成电路(例如,提供展示和用户界面的客户端)。代理传播与上述描述并无不同。数据消费在服务端与传统方法等效,区别在于集成电路了解服务期望的内容、所具有的属性、涉及的类型、约束以及考虑的验证等。
常见用例[4]针对服务维护,需考虑结构命名、属性命名、属性约束/验证 修改、属性删除以及主要的新增属性等方面的变更。使用ICs的服务如何响应这些变更?
使用数据传输对象的传统方法会受到任何推广到机器可读格式的服务结构变更的影响,从而导致集成电路端的不一致性。约束/验证的变更无法被及时获知,因此可能在生产环境中以不一致性的形式出现。
所提出的关注点分离方法无法处理给定结构的命名变更,因为集成电路的代理是由名称决定的,尽管基于键的间接寻址可以解决适应性问题。该代理反映了属性名称、约束和验证规则的所有服务变更,还能反映属性的增删。虽然它具备处理这些变更的能力,但集成电路应用程序可能会显式引用特定属性以执行业务处理或强制实施业务规则,从而限制了其适应性。[5,6]表明,在用户界面中这种情况很少发生,即使可能存在局部耦合。在用户界面中,通常采用通用方法来访问所有提供的字段,而不是进行显式引用。在用户界面中,结构表示可被视为一个逻辑单元。
当假设存在对给定结构的局部引用时,适应性会降低。集成电路应用不再适应属性名的变更或属性删除。尽管代理仍然具有适应性,但对已变更属性的引用可能会失败,类似于传统设计。另一方面,对约束和验证规则变更的适应性会将所有变更推广到ICs。因此,当服务维护遵循仅允许属性增量且允许约束/验证规则变更的策略时,则完整性被所有ICs保持并反映。这可以避免一致性错误并保持功能。
从上述内容可以看出,为了可维护性,最合适的方法是将业务规则嵌入到服务中,而不是集成电路中,这[13]对微服务具有建议意义。然后,IC适应性会促进大多数结构变化。然而,并非所有情况都允许将业务规则提升到服务中。此外,可能的目标设计是使用业务流程和规则间接性来促进业务变更和演进的灵活性。当然,无论业务规则源自何处,结构变化都必须促进引用业务规则,因此接下来我们考虑在多层之间重用单一业务规则定义的能力。
服务能力向其他ICs提供其业务规则,需要在捕获规则的方式上进行设计变更。[2,3]展示了可能的方法,该方法通过领域特定语言(DSL)捕获规则,并通过注解将规则与数据绑定。该方法带来了执行业务规则检查和转换的能力。这可以利用转换为机器可读格式,从而被独立的分发渠道使用。IC可以在本地解释所提供的规则,避免被拒绝的提交或提高可用性。在服务组合中,这带来了整合来自不同服务的业务规则以及从异构服务环境中获得各种规则集中视图的优势。跨服务共享业务规则的能力可在业务流程建模与执行中加以利用,尽管这部分内容留待未来工作进一步研究。
最具挑战性的视角是服务上下文感知。[4]建议,由于开发和维护需求,许多当代系统在用户界面设计中采用“一刀切”的方法。上下文可能影响数据的生产以及数据消费。我们很难想象数据值或结构表示会发生显著变化,最多仅限于属性访问限制或条件渲染。输入验证、约束或业务规则可能会根据上下文而有更显著的差异。例如,公司供应商代理只能在配送阶段开始前的某个时间点之前提交具有指定交货日期的订单。接受订单时间可能因订单目的地的地理位置而异,因为从中央仓库发货的时间会影响交付时间。作为对高交易量客户的额外优惠,代理可在截止时间之后提交订单。当代理更新客户资料时,必须提供所有个人信息,并遵守所提供格式的验证规则。管理员则可以使用部分信息更新客户资料,同时跳过所有验证规则。
上下文或多或少会影响其他被考虑的关注点,这会影响服务设计。[4]提出了一种基于AOP的方法,从开发角度来看,该方法与传统设计并无显著差异。数据模型及其引用验证、业务规则等内容的扩展被转换为连接点表示。该表示由切面织入器生成(一次),并由其用于中介服务请求。每次请求时,织入器都会克隆该连接点表示并分别考虑可能修改连接点表示的切面。切面根据提供的上下文以及在特定处理的表示部分中找到的连接点触发。因此,这可能会修改给定的约束、隐藏属性等。织入的结果如[5,6,14],所示,被转换为机器可读格式。相应的数据值遵循相同的周期,以确定哪些数据属性被授权用于交付。
上下文感知主要体现在用户界面中,用户界面会根据特定用户、浏览设备的能力、位置等进行调整。之前我们提到过[5,6]展示了针对移动设备、独立客户端和Web客户端的多个原型,这些原型能够处理与关注点相关的通信通道。当服务考虑上下文感知时,这些原型会根据提供的输出进行调整,从而具备上下文感知能力。这会影响缓存能力,并需要更严格的失效机制[6]。在不同平台上的使用表明了该方法的灵活性。此外,[6]显示,在Web交付中,该方法解耦了用户界面的关注点,并支持在集成电路端重用这些关注点,从而对服务性能产生积极影响。[6]提供了评估结果,表明在生产环境中,相较于传统的单通道交付,采用关注点分离的方法在用户界面响应速度方面表现更优,同时减少了服务端资源的消耗。
5 结论
本调查从关注点分离的角度讨论了服务集成。与以代码为中心的整体式方法相比,Web服务设计的传统方法带来了诸多优势。然而,服务集成存在多个缺陷。服务所涉及的数据结构必须被所有集成电路(ICs)理解并遵循,导致这些ICs与数据结构紧密耦合。这限制了服务的演进,通常需要引入新的、稍作修改的服务,以避免与遗留系统产生关联错误。此外,集成电路(ICs)不了解服务内部的约束、验证机制甚至业务规则。服务知识分发将提升性能、一致性及可用性,并为组合服务提供集中视图。
关注点分离与关注点分发解决了上述不足。服务可以通过所使用的多个分发渠道向ICs提供附加信息,提供数据结构语义以在运行时推导出服务数据结构表示。这克服了关于数据属性的紧密耦合问题。这具有两方面的影响。运行时推导使得IC能够适应服务端的结构变化,从而允许服务进行演化。相反地,IC使用在编译时不了解其属性的结构代理,除非引用服务本身。IC对特定属性的引用会引入耦合,并限制其对服务结构变化的适应性,尽管如[5,6]所示,通用引用可以被应用,正如在用户界面中的使用所展示的那样。其优点在于,代理表示包含了所有约束和验证规则,这些可以在IC上应用服务端,避免重复声明。在服务端采用合适的业务规则定义形式,能够检查规则定义,并以机器可读格式将这些规则通过独立的分发渠道提供给IC。此类规则可在请求处理的早期阶段应用,甚至与其他服务规则结合使用。IC层面的新业务规则定义可能受到该方法引入的弱类型安全影响。另一种解决方案是将业务规则提升为支持重用的特定服务,但会降低其修改和演进的灵活性。
上下文感知推动服务设计向面向切面编程(AOP)方向发展,因为它有助于实现避免代码纠缠和复制的高效设计。上下文会影响服务数据值的生产和消费,同时也会影响最终的数据结构表示、验证规则和业务规则。
我们的方法的主要优势在于能够使集成电路适应服务在数据结构方面的变更,尽管这种适应程度受到集成电路对数据结构属性引用的影响。该方法开放了元信息,从而与其他集成电路共享其约束、验证规则和业务规则,为它们提供了影响性能、可组合性和可用性的扩展能力。上下文感知的安全介入强制授权所有分发渠道。
未来工作将解决分布式环境中业务流程定义中的业务规则参与问题。集成电路开发中有限的类型安全可以通过针对服务提供的元信息的验证机制来增强。例如,IC 可以使用领域特定语言(DSL),如 MPS [17],作为验证工具。它可以利用元编程和适当的构造来解析有效引用。或者,在 Java 的情况下,我们甚至可以避免对 IC 设计的影响,并应用字节码操作框架,如 Apache BCEL 或 ASM [18]在开发/编译时强制实现属性关联。我们的研究还将考虑面向切面编程(AOP)方法用于服务的向后兼容性。每次服务发生变更时,都会引入一个新的切面,负责向后兼容性转换。ICs 可以使用给定的服务并指明兼容版本。该版本会触发一系列切面,这些切面对最新服务版本应用转换规则,并通过充当旧服务版本的 IC 来协调通信。
服务集成中的关注点分离

被折叠的 条评论
为什么被折叠?



