在服务交互的时候,数据是通过文档传递的。文档是显式建模的树状容器。在上面提到过的自描述性是面向文档的一个重要特征。理想状况下的文档应该是按照真实世界的文档来建模的,如采购单、发票或帐户声明。设计良好的文档在特定问题域的上下文环境中很有帮助,即它应该被一个或多个服务所采用。
类似于真实世界的纸质文档,在服务中交换的文档会包含冗余的信息。例如,客户的地址可能与客户的ID信息放在一起(尽管只有客户ID就足够了)。这些冗余的信息会被显式的使用,它的作用在于将服务和服务消费者和服务提供者的底层数据模型进行隔离。当使用面向文档模式的时候,服务调用成为了有意义的业务信息交换而不仅仅是上下文无关的RPC调用。尽管没有要求,一般都假定用XML来作为这种文档的格式/语法。
消息在通过SOA互连的异构系统间的参与者之间流动着。松耦合原则要求对于共有认知的依赖越小越好。当消息在分布式对象或RPC环境中传递时,客户端和服务端依赖的是一组用同一个接口描述文档自动生成的代理类(stubs和skeletons)。如果不采用这样的方式,若契约本身不支持双方交互则将无法通讯。所以说,RPC形式的架构必然要求客户端和服务端代码同步变化。
通过下面的比较我们来看一看。考虑以下消息:
“2006-03-1347113”
将它和
<order />
<date />2006-03-13</date />
<product />4711</product />
<quantity />3</quantity />
</order />
比较一下。
显然后者比前者的可读性更好,并且对于后者来说,除了使用固定的语法,参与者还可以使用例如XPath这样的技术来隔离细微的非颠覆性的变化。反过来说,如果用了像XML这样的自描述格式的消息却仍然使用RPC方式进行通讯,其作用无非只能证明XML是最消耗带宽的一种方式。如果你使用XML,那么一定要利用它的优点而不是缺点。
7)松耦合
大多数SOA倡导者都认同松耦合是一个重要的概念。但不幸的是,对于一个系统“松耦合”特性的认定却有很多不同的选项。认定一个系统是松耦合还是紧耦合的,根据具体的需求和上下文可以有许多维度,从某些维度来看可能是松耦合,但是从另一些维度来看又可能那是紧耦合。这些维度包括:
时间:当(服务)参与者在时间维度上松耦合时,他们不是必须同时在线才能进行交互。这要求他们之间必须有某种缓冲和队列的机制。当一个参与者发送消息到对方的时候,它不必依赖立即的消息回复也能继续流程。
位置:如果参与者需要知道其它参与者的位置信息来进行通讯,那么位置的松耦合意味着当这些位置信息的改变时应该不需要重新编程、重新配置或重新启动通讯中的各个参与者。这就隐含要求了服务的调用需要有一个寻址过程,并需要某种目录或地址簿存储服务终端的位置。
类型:类似编程语言中的静态类型/动态类型或强类型/弱类型,类型的松耦合使得服务的参与者不依赖文档的全部或哪怕部分结构。
版本:服务的参与者可能依赖特定版本的服务接口,也可能可以接口接口的(一定程度上)变化。越是依赖服务的特定版本,参与者的松耦合的程度就越低(在该维度上)。一个不错的参考准则是Postel法则:服务提供者的实现应当尽可能接受各种版本,以拥有更大的自由度(甚至可以容错),而服务的消费者则应该尽可能地遵循特定的语法和文档接口。这样可以增加系统整体上的可靠性和灵活性。
关联:在某些情况下,服务消费者和服务提供者之间是1:1的关系,尤其是在“请求-答复”式交互或使用显式的消息队列的情况下。而在另外一些情况中,服务的消费者(叫“消息发送者”或“事件源”更合适)可能不知道甚至根本不在乎收到的消息数。
查询:请求服务调用的参与者既可以根据服务提供者的(物理的或逻辑的)名字来跟它们通讯,也可以首先根据一组能力描述执行一个服务查找操作。这意味着需要有一个可以将消费者需求和服务提供者能力进行匹配的服务注册表或服务仓库。
接口:既可以要求参与者依赖服务所提供的特定接口,也可以要求它们支持一个通用的接口。如果使用通用接口,所有使用这个通用接口的参与者就可以和所有提供这个通用接口的参与者进行交互。尽管乍一看这样做非常别扭,但这种单一(统一)通用接口却是WWW结构中的核心所在。
任何创建的系统不可能、也不需要满足上述所有维度的松耦合。对于不同类型的服务需要做不同程度的权衡。
文章来源于领测软件测试网 https://www.ltesting.net/