洋葱架构深度指南:构建可测试可维护软件的精髓之道
洋葱架构(Onion Architecture)是一种将系统组织为同心层结构的架构模式,核心原则是"依赖指向中心"——外层依赖内层,内层完全独立于外层。
为什么需要洋葱架构?
传统的三层架构(表现层、业务逻辑层、数据访问层)存在一个根本性问题:业务逻辑层依赖数据访问层,这导致:
- 更换数据库需要修改业务代码
- 单元测试难以进行(难以mock数据层)
- 业务逻辑与基础设施紧耦合
洋葱架构通过依赖倒置原则解决这些问题。
洋葱架构的核心层次
┌─────────────────────────────────────┐
│ 基础设施层 (Infrastructure) │ ← 数据库、API客户端、文件系统
├─────────────────────────────────────┤
│ 应用层 (Application) │ ← 用例、编排、事务管理
├─────────────────────────────────────┤
│ 领域层 (Domain) │ ← 实体、值对象、领域服务
├─────────────────────────────────────┤
│ 核心层 (Core) │ ← 业务规则、接口抽象
└─────────────────────────────────────┘
1. 核心层(Domain Core)
最内层,完全独立,不依赖任何外部:
# 领域实体
class Order:
def __init__(self, order_id, items):
self.id = order_id
self.items = items
self.status = "pending"
def total(self):
return sum(item.price * item.quantity for item in self.items)
def can_cancel(self):
return self.status == "pending"
2. 领域层(Domain)
定义业务接口,不实现:
# 领域接口(抽象)
class IOrderRepository:
def save(self, order: Order): pass
def find_by_id(self, order_id): pass
class IPaymentService:
def process_payment(self, order: Order): pass
3. 应用层(Application)
用例(Use Cases)所在,协调领域对象:
class CreateOrderUseCase:
def __init__(self, order_repo: IOrderRepository):
self.order_repo = order_repo
def execute(self, order_data):
# 创建订单
order = Order(order_data["id"], order_data["items"])
self.order_repo.save(order)
return order
4. 基础设施层(Infrastructure)
实现领域层定义的接口:
class PostgresOrderRepository(IOrderRepository):
def __init__(self, db_connection):
self.db = db_connection
def save(self, order):
# 实际的数据库操作
self.db.insert("orders", order.__dict__)
依赖流向:关键原则
所有依赖都指向内层,通过依赖注入实现:
表现层 → 应用层 → 领域层 → 基础设施层
↑ ↑ ↑ ↓
└─────────┴─────────┴─────────┘
依赖注入
依赖注入示例:
# 运行时注入实现
order_repo = PostgresOrderRepository(db_connection)
create_order = CreateOrderUseCase(order_repo)
实战:用DI容器管理依赖
from injector import Injector
# 注册绑定
injector = Injector()
injector.bind(IOrderRepository, to=PostgresOrderRepository)
injector.bind(IPaymentService, to=StripePaymentService)
# 注入使用
order = injector.get(CreateOrderUseCase).execute(data)
洋葱架构 vs 传统分层
| 维度 | 三层架构 | 洋葱架构 |
|---|---|---|
| 依赖方向 | 上层→下层 | 外层→内层 |
| 业务逻辑 | 在Service层 | 在Domain层 |
| 可测试性 | 困难 | 容易 |
| 替换数据库 | 修改业务代码 | 仅替换Infrastructure |
| 依赖注入 | 可选 | 必需 |
何时使用洋葱架构?
✅ 适合场景:
- 中大型复杂业务系统
- 需要频繁更换数据存储
- 高度可测试性要求
- 微服务内部架构
❌ 不适合场景:
- 简单CRUD应用
- 快速原型验证
- 小型脚本工具
总结
洋葱架构的核心理念:
让核心业务逻辑完全独立于基础设施
通过依赖指向中心的组织方式,我们实现了:
- 🎯 高度可测试
- 🔄 易于替换组件
- 📦 清晰的责任边界
- 🛠 长期可维护
这是构建企业级应用的坚实基础。
下期预告:六边形架构(Hexagonal Architecture)与洋葱架构的对比与融合。
如果你觉得这篇文章有帮助,欢迎关注、点赞、转发!我是@甜心,上午好!🍬
Top comments (0)