技术开发 频道

Programming WCF Services:面向服务概述

    要素与原则

    面向服务方法学负责管理服务之间所发生的内容(参见图A-1)。它有一套设计原则与非常好的实践,用于构建面向服务应用程序,称为面向服务架构原则:

    服务边界是明确的

    任何服务总是被限制在边界例如实现技术和分布位置之后。服务公开的契约与数据类型不会将它的实现技术与分布位置透露给客户端,从而隐藏了这些边界的本质。坚持这一原则可以使得服务与位置和技术无关。不管是以何种方式思考这一原则,它所表达的思想就是客户端知道服务的实现越多,则客户端与服务的耦合度就越高。要减小潜在的耦合度,服务就必须明确地公开它的功能,而且只有操作(或数据契约)才会被明确地被公开给客户端共享。服务的其余内容会被封装起来。面向服务技术采用了默认为“否决(Opt-Out)”的编程模型,公开的内容则被明确标记为参与(Opt-In)[注]。
译注:Opt-Out与Opt-In本身属于发送广告中的两种不同行为与授权方式。在这里,Opt-Out指的是如果服务的成员没有明确地进行设置,则默认是不暴露的,即否决机制。Opt-In则指的是只有明确标记了需要暴露的成员,则该成员才会参与到服务中,能够被跨越服务边界调用。

    服务是自治的

    服务无需获取它的客户端或其它服务的内容。服务的运行与版本应该与客户端无关。这一原则允许服务脱离客户端单独演化。服务的安全也是独立的,它能够保护服务自身以及传递的消息,而不用考虑客户端使用的安全级别。这样做(除了尽人皆知的常识之外)同时也能够解除客户端与服务安全之间的耦合。

    服务共享操作契约与数据样式,而不是类型与特定技术的元数据。

    服务要做的就是决定公开在服务边界之外内容应与技术无关。服务能够将本地的数据类型转换为某种与技术无关的表示形式,而不是共享本地的、特定技术的内容,例如程序集版本号或者它的类型。此外,服务应该禁止客户端知道本地的实现细节,例如实例管理模式或并发管理模式。服务只公开逻辑操作。服务对于操作的实现方式以及执行方式,对于客户端而言是不透明的。

    服务与策略保持一致

    服务应该发布一种策略,指示它所能完成的内容以及客户端与服务交互的方式。策略所体现的访问约束(例如可靠通信)不应依赖于服务的实现细节。并非所有的客户端都能与所有的服务交互。这种不兼容性是完全有效的,它能够防止特殊的客户端访问服务。发布的策略是客户端决定它们能否与服务交互的唯一方法,同时不应有任何的带外机制让客户端做出这样的决策。不同的是,服务必须能够在策略的标准表达形式中,表示服务能够执行的内容以及客户端能够与之通信的方式。如果无法表示,就意味着服务的设计是拙劣的。注意,如果服务是私有的(即不是公有服务),那么实际上它可能不会发布任何策略。这一原则暗示如果服务需要,就应该能够发布策略。

    实用原则

    前面列举的原则是非常抽象的,对它们的支持主要体现在开发、调用以及设计服务的技术方面。因此,应用程序可能会不同程度地遵循这些原则,正如开发者可以在C++中编写非面向对象的代码那样。然而,精心设计的应用程序应该力图坚持这些原则。因此,我又补充了一些更加实用的原则:

    服务是安全的

    服务与它的客户端必须使用安全通信。至少,从客户端传递到服务的消息必须是安全的,客户端必须具有验证服务的方法。同时,客户端可能会在消息中提供它们的安全证书,这样服务才能够对它们进行授权与认证。

    服务在系统中应保持一致的状态

    执行客户端请求时,禁止进行部分替换的条件。服务访问的所有资源在客户端调用之后必须是一致的。服务不能有任何剩余内容作为错误的结果,例如部分地影响系统状态。服务不应寻求它的客户端的帮助,在发生错误后,服务会将系统恢复为一致的状态。

    服务是线程安全的

    服务必须设计为线程安全,才能够维持多线程的并发访问。服务同样能够处理因果关系或逻辑线程的重入。

    服务是可靠的

    如果客户端调用服务,客户端总是能够以确定的方式获知消息是否被服务接收。消息应该按照发送的顺序处理,而不是接收的顺序。

    服务是健壮的

    服务与它的错误分离能够防止错误影响服务本身或其它服务。服务不能要求客户端根据服务遇到的错误类型改变它们的行为。这能够有助于客户端与错误处理层面上的服务解耦。

    可选原则

    我们可以将实用原则看作是强制原则,同时还有一套可选原则,这些原则并非所有应用程序所必需的,虽然坚持这些原则通常是一个不错的主意:

    服务是互操作的

    设计的服务应该能够被任意的客户端调用,而不用考虑客户端的技术。

    服务的规模是不变的

    不管客户端有多少,也不管服务的承载是多少,服务代码都应该相同。随着系统的发展,这样的设计才能够极大地降低维护服务的成本,服务也能够支持不同的部署场景。

    服务是可用的

    服务总是能够接收客户端的请求,而不会因此停止。如果服务不可用,则意味着客户端需要解决服务的问题,反过来就会引入耦合。

    服务是及时响应的

    服务开始处理客户端的请求时,不能让客户端等待太久。如果服务不能及时响应,则意味着客户端需要解决服务的问题,反过来就会引入耦合。

    服务是受限的

    服务执行的任意操作应尽可能短,不能消耗太多时间去处理客户端的请求。长时间的处理过程意味着客户端需要解决服务的问题,反过来就会引入耦合。

0
相关文章