六边形架构(Hexagonal Architecture):如何/何处将两个适配器合并为一个实体
关于六边形架构的两个问题解答
核心问题:账户数据合并操作的位置选择
在六边形架构的约束下(领域层不依赖适配器、适配器间互不感知),合并Mongo扩展数据与Stripe账户数据的操作,推荐放在以下两个位置:
- 应用层(Application Layer):作为领域与适配器之间的协调层,应用服务可以依赖两个适配器对应的抽象端口(如
MongoAccountPort和StripeAccountPort),分别调用端口获取两类账户数据,在应用服务内完成合并后,将完整的AccountEntity传递给领域层使用。这种方式下,应用层仅负责调用编排,不包含业务逻辑,符合六边形架构的职责划分。 - 领域服务(Domain Service):如果合并操作涉及业务规则(比如字段校验、默认值填充、业务逻辑校验),可以在领域层定义专门的账户聚合服务,通过依赖注入上述两个抽象端口,在服务内部完成数据获取与合并。注意:领域服务应聚焦业务逻辑,纯数据组装类的合并更适合放在应用层。
无论选择哪种方式,核心原则是:领域层和应用层仅依赖抽象端口,不直接依赖具体的Mongo或Stripe适配器,保持架构的隔离性和可替换性。
附带问题:Stripe适配器独立于领域层的价值
即使当前领域与Stripe存在耦合,保留独立的Stripe适配器依然有长期价值,理由如下:
- 解耦依赖:适配器隔离了Stripe SDK的具体实现与领域逻辑,未来如果需要切换支付网关(如从Stripe换成PayPal),仅需替换适配器实现,无需修改领域层代码。
- 边界清晰:适配器统一处理与Stripe API的交互(如请求重试、错误处理、参数封装),避免这些非业务逻辑侵入领域层,保持领域层的纯粹性。
针对样板代码过多的问题,可以通过以下方式优化:
- 使用映射工具(如MapStruct)自动生成领域实体与Stripe SDK实体之间的转换代码,减少手动编写的样板。
- 定义领域友好的
StripeAccountDTO,适配器负责将Stripe API响应转换为该DTO,领域层仅与DTO交互,而非直接依赖Stripe的SDK类。
如果业务确实高度绑定Stripe且短期内无替换计划,可以适当简化适配器的实现,但仍建议保留抽象端口的设计,为未来的扩展性预留空间。
内容的提问来源于stack exchange,提问作者Thomas KLING
相关产品推荐
相关产品推荐

