最小化集成
在所有的DDD项目中,通常存在多个限界上下文,这意味着我们需要找到合适的方法对这些上下文进行集成。当模型概念从上游上下文流人下游上下文中时,尽量使用值对象来表示这些概念。这样的好处是可以达到最小化集成,即可以最小化下游模型中用于管理职责的属性数目。使用不变的值对象使得我们做更少的职责假设。
为什么要如此负责任?
使用不变的值对象使得我们做更少的职责假设。
重用限界上下文(2)中的一个例子:上游的身份与访问上下文会影响下游的协作上下文,如图6.1所示。在身份与访问上下文中,两个聚合分别为User和Role。在协作上下文中,我们关心的是一个User是否拥有一个特定的Role,比如Moderator。协作上下文使用它的防腐层(3)向身份与访问上下文的开放主机服务(3)提出查询。如果这个集成的查询过程表明某个User拥有Moderator角色,协作上下文便会创建一个代表性的Moderator对象。
Moderator和其他Collaborator的子类如图6.2所示,这些对象被建模成了值对象。这些值对象的实例通过静态方式创建,并且和一个Forum聚合关联。这里的重点在于,上游的身份与访问上下文对下游的协作上下文的影响被最小化了。虽然上游上下文需要处理许多对象属性,但是它传给下游的Moderator却只包含了通用语言中的关键性属性。此外,Moderator并不包含Role聚合中属性,而是通过自身的名字表明一个用户所扮演的角色。我们选择静态创建Moderator的方式,并且没有必要使下游中的值对象与上游保持同步。这种考虑了服务质量(Quality Of Service)的契约可以大大地减轻下游上下文的负担。
当然,有时下游上下文中的对象必须和远程上下文中的聚合保持最终一致性。在这种情况下,我们可以在下游上下文中设计一个聚合,因为该聚合实体可以用于维护状态变化。但是,我们应该尽量地避免这种建模方式,在有可能的情况下使用值对象来完成限界上下文之间的集成,这对于许多需要消费标准类型的上下文来说都是适用的。