知识卡片

服务层瘦身程度的两极与折中:控制器-实体风格

结构图卡

内容

服务层里该放多少行为,是一个需要认真权衡的决定,作者把它看成一个连续谱。最小化的一极:服务层只是一个纯外观,真正的行为全在下层对象里,服务层只负责把上层调用原样转发下去,好处是方法通常按用例组织、更易用,同时是加事务封装和安全检查的天然切入点。最大化的另一极:把大部分业务逻辑都以事务脚本的形式直接塞进服务层,下层领域对象因此变得极简——如果下层是领域模型,这些对象甚至可以退化成与数据库一一对应,从而用上活动记录这类更简单的数据源层。二者的折中是”控制器-实体”风格(术语受[Jacobson et al.]影响):把单个事务/用例特有的逻辑放进事务脚本形式的”用例控制器”里,而可被多个用例复用的行为则放进被称为”实体”的领域对象里。作者本人对控制器-实体风格并不很欣赏:和纯事务脚本一样,用例控制器容易产生代码副本;作者的立场是——如果真的决定用领域模型,就该彻底贯彻,让它在应用中占主导地位,不要搞半吊子的折中;只有一种例外情况值得从行数据入口的事务脚本挪一部分冗余行为进去,把它逐步改造成基于活动记录的简单领域模型,但这只用来改进已有缺陷设计,不作为起手方案。作者自己的默认建议是:先假定不需要服务层,等应用确实需要时再加,且倾向于让服务层尽量最小化;但也承认不少优秀设计者习惯让服务层承载更多逻辑,这是合理的另一种取舍。

结构图

flowchart LR
  A["最小化服务层<br/>纯外观,转发调用"] --- B["控制器-实体风格<br/>用例逻辑进控制器<br/>复用逻辑进实体"] --- C["最大化服务层<br/>事务脚本式,装满业务逻辑"]
  B -.->|"作者保留态度:<br/>易产生代码副本"| B
  A -.->|"作者默认倾向"| A

参考来源

- 位置:《企业应用架构模式》第一部分"表述"之"第2章 组织领域逻辑"之"2.2 服务层"(源文件:_epub-src/OEBPS/Text/000016.html) - 结论依据:原文说明"最小化情况下,服务层只是一个外观……另一个极端则是将大多数业务逻辑都以事务脚本的形式置于服务层中……以上二者的折中是一个行为的混合体:控制器-实体风格……虽然控制器-实体方法很常用,但我一直不是很欣赏它。与事务脚本一样,用例控制器容易产生代码副本",并总结"我的建议是:如果你确实需要,尽可能使用最小化的服务层",直接支撑本卡结构图。 - 原始内容:我认为,如果你确实决定完全选用领域模型,就应当彻底贯彻这一模式,使它在应用程序中占主导地位……因此,我的建议是:如果你确实需要,尽可能使用最小化的服务层。我通常首先假定并不需要这么一层,然后当发现应用确实需要时才增加。