hexagonal architecture(六边形架构)中应在何处手动实例化adapters
六边形架构下适配器实例化的正确位置
你之前把DI启动逻辑放在应用层是导致耦合的核心原因,按照六边形架构的依赖规则,所有外层(适配器层、基础设施层)都只能依赖内层(应用层、领域层),内层绝对不能依赖外层的具体实现。
你可以把整个DI组装、适配器实例化的逻辑抽出来,单独放在独立的*组装层(Composition Root)*里,这个层属于项目最外层的基础设施范畴,和你实现的DB适配器、HTTP适配器同属外层,不会违反依赖规则。
具体的分层逻辑可以参考如下结构:
- 领域层:纯业务逻辑、端口定义,无任何外部依赖
- 应用层:业务编排、依赖端口抽象,不依赖任何具体适配器实现
- 适配器层:各类入站/出站适配器的具体实现,仅依赖内层定义的端口抽象
- 组装层:单独的项目/模块,或者就是项目的主入口文件,唯一职责是实例化所有适配器、注入到应用层需要的位置,启动整个应用
你不需要修改应用层的任何代码,只需要把原本在应用层里的DI实例化逻辑全部移到组装层即可:
- 应用层只保留对端口的依赖声明,不涉及任何适配器的实例化代码
- 组装层持有所有适配器、应用服务的实例化逻辑,直接把实例化后的适配器实现注入给应用层的构造参数
这种做法的优势是:
- 应用层完全不感知适配器的具体实现,彻底解耦内层和外层
- 更换适配器实现时不需要修改应用层代码,只需要修改组装层的实例化逻辑
- 单元测试时可以直接在测试代码里实例化mock适配器注入应用层,不需要修改业务代码
注意:如果你的项目规模很小,不需要单独拆分组装层模块,直接把所有实例化逻辑放在项目启动的入口文件(比如Java的
Main类、Go的main.go、Node.js的index.js)里即可,这个入口文件本身就属于最外层的基础设施,不会违反依赖规则。
内容的提问来源于stack exchange,提问作者Carlos Sanmartín Bustos
相关产品推荐
相关产品推荐

