知识卡片
服务层是否远程的建议:先本地,后按需加远程外观
内容
服务层的接口声明的是一组面向客户层的应用操作,定义上就是粗粒度的,这让它天生适合远程调用——但适合不等于应该。为服务层方法处理数据传输对象、应对分布带来的额外工作量不容小觑,尤其当领域模型复杂、又有大量复杂更新用例的编辑界面时,这份工作量既重要又痛苦,痛苦程度大概仅次于对象-关系映射本身——这正呼应了”分布对象设计第一定律”(不要分布使用对象)。作者的具体建议是:一开始只设计一个本地调用的服务层,方法签名里直接使用领域对象即可;等真正需要远程调用能力时,再在服务层之上叠加一层远程外观,或者让服务层对象自己实现远程接口。即便应用有基于Web的用户界面或基于Web Service的集成入口,也没有任何硬性规定说业务逻辑必须运行在和服务器页面/Web Service分离的进程里——完全可以把它们放在同一个进程里,这样不但不会牺牲可伸缩性,还能省下一部分开发工作量和运行时的响应时间。可迁移启发:粗粒度接口”适合”远程调用,不代表应该提前为它设计远程能力——按需渐进引入分布式设计(先本地跑通、有真实需求再加远程外观),比一开始就假设”迟早要分布式”更划算。
参考来源
- 位置:《企业应用架构模式》第二部分"模式"之"第9章 领域逻辑模式"之"9.4.1 运行机制"(源文件:_epub-src/OEBPS/Text/000071.html)
- 结论依据:原文说明"我的建议是开始时仅设计一个本地调用的服务层,其方法标记中仅处理领域对象。当你需要远程调用功能时,再通过在服务层之上增加一个远程外观来实现……现在还没有硬性规定:业务逻辑必须运行在一个与服务器页面或Web Service相分离的进程中。事实上,你可以在不牺牲可伸缩性的前提下将它们放在一起,从而节省一些开发工作量和运行时的响应时间",直接支撑本卡结论。
- 原始内容:不要低估这一工作量,尤其是你有一个复杂领域模型,而且对那些复杂的更新用例有大量编辑界面时。这一工作很重要,但也很痛苦——其代价和痛苦程度可能仅次于对象到关系数据库的映射。