跳转到内容

洋葱架构与整洁架构

用途:比较同心圆风格与六边形的差别,决定团队采用哪套术语

洋葱架构(Jeffrey Palermo 提出)把系统组织为同心圆:领域核心 → 内部服务 → 外部服务 → 基础设施,依赖只能由外向内。

整洁架构(Robert C. Martin)给出更一般的分层:实体(Entities)→ 用例(Use Cases)→ 接口适配器(Interface Adapters)→ 框架与驱动(Frameworks & Drivers),并规定源码依赖只能指向内圈,内圈不知道外圈的任何细节。

三者表达的是同一个约束,差别在术语与强调点:

维度 六边形 洋葱 整洁架构
图形 中心 + 两侧端口 同心圆 同心圆 + 边界
强调 输入/输出端口对称 依赖只能向内 边界与可测试性、框架可替换
术语 端口/适配器 内部/外围服务 Entities/Use Cases/Adapters
用例的位置 应用核心 内圈 第二圈(应用层)

团队只需要选一套术语并坚持,混用会制造无谓的目录争论。

  1. 依赖规则:内圈不 import 外圈。用架构测试(ArchUnit、dependency-cruiser、jdeps + 脚本)在 CI 强制。
  2. 边界处才转换模型:Entity 只在核心内流转;跨边界用 DTO;持久化用独立结构。
  3. 框架是细节:Web 框架、ORM 可以替换,业务代码不应依赖其类型(至少不依赖其注解承载语义)。
  4. 用例可独立测试:不启动框架即可验证业务行为。
收益 成本
业务逻辑集中、可测试 模型转换样板代码增多
技术栈替换影响面小 新人需要理解抽象方向
变更隔离(改 UI 不动业务) 简单场景显得绕

成本收益与系统复杂度正相关:核心域值得投入,通用域与工具模块不必套用。

误区 修正
画同心圆但依赖方向随意 用架构测试强制,否则只是文档
用例层写满业务规则 规则属于实体(聚合),用例只编排
每层都建一套模型且互相映射十几次 只在真正的边界处转换
把框架隔离做到极端(连语言标准库都封装) 目标是隔离易变的技术决策
用架构名词替代领域建模 分层不产生模型,模型来自业务分析
  • Jeffrey Palermo《Onion Architecture》系列文章
  • Robert C. Martin《Clean Architecture》第 13、22 章
  • Alistair Cockburn 关于端口适配器的论述(与上述风格对照)