面向服务架构
面向服务架构(Service-Oriented Architecture, SOA)对于不同的人来说具有不同的意思。这对于讨论SOA架构来说可能是一种挑战,因此我们最好能找到一些共同的基础,或者至少应该给出一些定义以便讨论。我们可以考虑由ThomasErl[Erl]所定义的一些SOA原则。服务除了拥有互操作性外,还具有以下8种设计原则,如表所示。
服务设计原则 | 描述 |
---|---|
1.服务契约 | 通过契约文档,服务阐述自身的目的与功能 |
2.松耦合 | 服务将依赖关系最小化 |
3.服务抽象 | 服务只发布契约,而向客户隐藏内部逻辑 |
4.服务重用性 | 一种服务可以被其他服务所重用 |
5.服务自治性 | 服务自行控制环境与资源以保持独立性,这有助于保持服务的一致性和可靠性 |
6.服务无状态性 | 服务负责消费方的状态管理,这不能与服务的自治性发生冲突 |
7.服务可发现性 | 客户可以通过服务元数据来查找服务和理解服务 |
8.服务组合性 | 一种服务可以由其他的服务组合而成,而不管其他服务的大小和复杂性如何 |
我们可以将这些原则和六边形架构结合起来,此时服务边界位于最左侧,而领域模型位于中心位置,如图4.5所示。消费方可以通过REST、SOAP和消息机制获取服务。请注意,一个六边形架构系统支持多种类型的服务端点(endpoint),这依赖于DDD是如何应用于SOA的。
由于对于SOA的定义和SOA的价值存在不同的观点,即便你不同意图4.5也是可以理解的。Martin Fowler将这种情况称为“面向服务歧义” [Fowler,SOA]。因此,这里我不会试图消除对SOA的歧义理解,但我会讲到将DDD应用于SOA的一种方式,此时我主要关注SOA宣言3中出现的首要原则。
3. 虽然 SOA 宣言本身招致了很多批评, 但我们引燃可以从中获得一些价值. ↩
首先,让我们看看其中一位宣言贡献者[Tilkov,Manifesto]的观点。该贡献者的评论有助于我们理解SOA到底是什么:
SOA宣言给我的感觉是,我既可以将服务看作一系列的SOAP/WSDL接口,也可以将其看成为一组REST资源...本宣言并不试图给SOA下定义,而是找出我们都同意的SOA的价值和原则。
Stefan的评论是值得注意的,在某个问题上达成一致对我们是有帮助的。我们甚至可以在这一点上达成一致:业务服务可以由任意数目的技术服务来提供。
技术服务可以是REST资源、SOAP接口或者消息类型。业务服务强调业务战略,即如何对业务和技术进行整合。然而,定义单个业务服务与定义单个子域(2)或限界上下文是不同的。在我们对问题空间和解决方案空间进行评估时,我们会发现,此两者均包含有业务服务。因此,图4.5所示的只是单个限界上下文的架构,该限界上下文可以提供一系列的技术服务,包括REST资源、SOAP接口或者消息类型,而这些技术服务只是整个业务服务的一部分。在SOA的解决方案空间中,我们希望看到多个限界上下文,而不管这些上下文使用的是六边形架构还是其他架构。SOA和DDD均没有必要制定如何对技术服务进行设计和部署,因为存在很多种这样的方式。
在使用DDD时,我们所创建的限界上下文应该包含一个完整的,能很好表达通用语言的领域模型。在限界上下文(2)中我们已经提到,我们并不希望架构对领域模型的大小产生影响。但是,如果一个或多个技术服务端点,比如REST资源.SOAP接口或消息类型被用于决定限界上下文的大小,那么上述情况是有可能发生的,结果是将导致许多非常小的限界上下文和领域模型,这样的模型中很有可能只包含一个实体对象,并且该实体作为某个单一聚合的根对象而存在。
虽然这种方式在技术上具有优点,但是它却没有达到战略DDD所要求的目标。对于通用语言来说,这种方式会起分化破坏作用。而根据SOA宣言,非自然地分化限界上下文并不是SOA精神所在:
- 业务价值高于技术策略
- 战略目标高于项目利益
就像限界上下文(2)中所讲到的,技术组件对于划分模型来说并没有那么重要。
SaaSOvation的开发团队不得不上很困难但又很重要的一课一一将通用语言作为驱动更适合于DDD。他们所有的3个限界上下文所反映的都是SOA的目标,包括SOA的业务服务和技术服务。
在限界上下文⑵、上下文映射图(3)和集成限界上下文(13)中提到的3个
示例模型分别表示了某个能很好反映通用语言的领域模型。每一个领域模型由一组SOA开放服务所包围,这些服务是满足业务目标的。