知识卡片
远程外观与服务层的关系:能否共存
内容
远程外观和服务层看起来很像(都提供一个相对粗粒度的外部入口),但两者的定位并不相同。最本质的区别:服务层不需要是远程的,因此也不需要局限于粗粒度方法——服务层为了简化领域模型,方法确实经常收敛成粗粒度,但这是为了让结构更清晰,而不是为了节省网络开销;服务层通常也不需要用数据传输对象,往往可以直接把真正的领域对象返回给客户。这个区别引出了一个实用的架构决策:如果一个领域模型既要支持进程内调用、又要支持远程调用,可以让服务层继续按它本来的样子实现(进程内直接返回领域对象),再在服务层之上单独叠加一层远程外观专门服务远程客户;如果应用从头到尾只走远程这一条路,作者认为直接把服务层改造成远程外观反而更省事、更容易,前提是这个服务层本身不包含额外的应用逻辑——一旦服务层里确实塞了应用逻辑,作者的建议是让远程外观独立成另一个对象,而不是把两者硬合并。可迁移启发:判断两个看起来相似的架构层(比如这里的服务层与远程外观)该不该合并实现,关键要看它们各自的存在理由是否本质相同——如果一个是为了简化领域模型的调用体验,另一个是为了压低网络调用次数,即便表现形式高度重合,也应该保留拆分的可能性,以便按需独立演化,而不是因为长得像就强行融合成一个东西。
参考来源
- 位置:《企业应用架构模式》第二部分"模式"之"第15章 分布模式"之"15.1.1 运行机制"(源文件:_epub-src/OEBPS/Text/000181.html,见原书"2. 服务层"小节)
- 结论依据:原文说明"它们之间最大的不同是服务层不需要是远端的,因此并不需要只有粗粒度方法……通常,它返回给客户一个真正的领域对象。如果一个领域模型同时在进程内和远程使用,那么你可以有一个服务层并在这个服务层上分出一个单独的远程外观层……如果服务层中包含了一些应用逻辑,那么我将使远程外观成为一个单独的对象",直接支撑本卡结论。
- 原始内容:如果进程只是在远程执行,那么这种方法将会很容易把服务层转换成远程外观,并且在服务层中不包含任何应用逻辑。