知识卡片

接口的信息隐藏作用:防止传递性依赖,而非只是反转方向

普通读书笔记卡

内容

[[OCP在架构层面的核心机制不想被修改影响的组件应被依赖]]里引入的一些接口承担着两种不同的职责,容易被混为一谈。FinancialDataGateway这类接口,作用是反转Interactor与Database之间的依赖关系——这是最直观的用法,接口帮助控制”谁依赖谁”的方向。但FinancialReportRequester这样的接口,作用完全不同:它是用来保护FinancialReportController,不让它过度依赖Interactor的内部实现细节。如果没有这个接口,Controller就会传递性地依赖上Interactor内部使用的FinancialEntities——即便Controller的代码里从没直接用到FinancialEntities,只要它依赖了没有接口隔离的Interactor,它就间接地”背上”了这个依赖,一旦FinancialEntities的内部结构变了,Controller也可能被牵连需要重新编译或调整。这违反了一条基本原则:软件系统不应该依赖它不直接使用的组件。因此,即便系统主要目的是让Interactor屏蔽Controller层的修改,同样重要的是反过来:用接口隐藏Interactor的内部细节,让它对Controller的暴露仅限于Controller真正需要用到的那一小部分。发散:这个区分预告了后续接口隔离原则(ISP)和共同复用原则要处理的问题——依赖方向的反转和信息隐藏的传递阻断,是接口这个工具能同时干的两件不同的事,混淆二者会让人误以为”加一层接口”就万事大吉,却漏掉了接口真正该暴露多少信息这个更精细的问题。

参考来源

- 位置:《架构整洁之道》第8章《OCP:开闭原则》"依赖方向的控制""信息隐藏"(源文件:_epub-src/text/part0012_split_002.html) - 结论依据:原文区分FinancialDataGateway接口用于反转依赖方向、FinancialReportRequester接口用于防止Controller传递性依赖FinancialEntities两种不同作用,并明确指出"软件系统不应该依赖其不直接使用的组件"这一原则,直接支撑本卡片结论。 - 原始内容:FinancialReportRequester接口的作用则完全不同,它的作用是保护FinancialReportController不过度依赖于Interactor的内部细节……这种传递性依赖违反了"软件系统不应该依赖其不直接使用的组件"这一基本原则。