知识卡片

连接件嫉妒:组件僭越连接件职责

普通读书笔记卡

内容

Garcia等人根据实践经验定性描述了11种架构坏味道(连接件嫉妒、过度分散的功能、模糊接口、无关的相邻连接件、砖关注过载、砖使用过载、砖循环依赖、未使用接口、重复的组件功能、组件嫉妒、连接件链),其中连接件嫉妒(Connector Envy)是指本该由连接件负责的通信、简化功能被组件自己实现了——组件与连接件的职责边界被打破。两个典型场景:一是组件自己导入通信器直接实现远程通信,把命名、交付、路由这些本属于连接件的”简化功能”也一并揽了过去;二是组件在实现接口服务时,自己内嵌了参数类型转换逻辑(如把笛卡儿坐标转成屏幕坐标),而这种转换本该由连接件完成。这种坏味道容易被误解为”组件功能更全不是好事吗”,但代价体现在三个方面:可重用性降低,因为交互服务和专有服务之间产生了依赖,导致只想复用专有服务却做不到,若两者都复用又会造成功能冗余甚至冲突(例如一个坐标转换组件被搬到一台本身就用屏幕坐标传数据的新机器上,组件里那段转换逻辑就变成了多余甚至出错的累赘,但因为功能和组件绑死,想去掉又会破坏可重用性);可理解性降低,因为专有关注点和交互关注点混在一起,无法看清组件到底在干什么正事;可测试性降低,因为两种功能无法拆开单独测试,一旦测试失败也难以判断根因究竟出在哪一层。不过连接件嫉妒不是必须消除的坏味道——如果系统对性能的要求远高于可维护性,把交互机制从专有功能中分离出来会引入额外中间层、可能需要额外进程或线程,反而拖累整体性能,尤其是使用简单交互机制的高度资源约束型应用,保留连接件嫉妒反而可能是收益更高的选择。但若放任不管,代价可能是灾难性的:为了让功能仍然可用,必须在所有组件里重复植入互不兼容的连接类型,导致代码规模指数级膨胀。这条权衡逻辑揭示了架构坏味道判断的通用原则——某种设计是否算”坏味道”需要负分收益,而不是脱离场景的绝对禁令。

参考来源

- 位置:《软件架构理论与实践》第20章《软件架构坏味道》"20.3.1 架构坏味道"第1小节"连接件嫉妒"(源文件:_epub-src/OEBPS/text00171.html) - 结论依据:原文描述"ComponentA实现了本该委托给连接件来实现的通信功能和简化功能"及"这个转换过程应该由连接件实现完成的"两个案例,并总结"广泛地将连接件与组件的功能相连接导致的连接件嫉妒会降低组件的可重用性、可测试性和可理解性",同时给出性能优先场景下可容忍该坏味道的权衡说明,直接支撑本卡片结论。 - 原始内容:ComponentA实现了本该委托给连接件来实现的通信功能和简化功能:ComponentA导入了一个通信器,也就意味着它可以通过这个低级的网络通信设备实现远程通信……如果该系统对于性能的要求远大于可维护性,那么系统中出现连接件嫉妒是可以容忍的。