3. 领域驱动设计(DDD)基础:实体、值对象、聚合、聚合根、领域事件、限界上下文
领域驱动设计(Domain-Driven Design,DDD)为BFF(Backend For Frontend)架构提供了核心的建模方法论。BFF作为前端与后端之间的中间层,其核心职责是为特定前端用例提供精准的领域能力编排。理解DDD的六大基础构造块,是设计高内聚、低耦合BFF聚合根的前提。
3.1 实体(Entity)与值对象(Value Object)
实体和值对象是领域模型中最基本的两种对象类型,它们的区别决定了BFF中数据模型的边界划分方式。
| 特征 | 实体(Entity) | 值对象(Value Object) |
|---|---|---|
| 标识 | 拥有唯一标识(ID),标识贯穿生命周期 | 无唯一标识,由属性值定义相等性 |
| 可变性 | 允许状态变化,标识不变 | 不可变(Immutable),修改即替换 |
| 生命周期 | 独立存在,可被追踪 | 依附于实体,无独立生命周期 |
| 相等性 | 通过ID判断 | 通过所有属性值判断 |
| BFF典型场景 | 用户、订单、商品 | 地址、金额、时间段、坐标 |
BFF建模提示:在BFF层,值对象常用于封装前端展示所需的组合数据(如“用户简介视图”),这些数据不需要独立ID,仅作为响应DTO的一部分存在。将值对象设计为不可变,能有效避免BFF层因意外修改数据导致的跨请求状态污染。
3.2 聚合(Aggregate)与聚合根(Aggregate Root)
聚合是领域模型的事务一致性边界,聚合根是聚合中唯一能被外部引用的实体。BFF的每个接口端点,本质上都是在操作一个或多个聚合根。
- 聚合(Aggregate):一组相关对象的集群,对外表现为一个整体。内部对象之间通过聚合根进行协调。
- 聚合根(Aggregate Root):聚合的入口点,外部只能通过聚合根的方法修改聚合内部状态。
- 边界规则:一次事务只修改一个聚合;聚合之间的最终一致性通过领域事件实现。
核心原则:BFF的每个API端点应尽量只操作一个聚合根。如果必须跨聚合,应通过BFF编排层调用多个领域服务或聚合根方法,并在BFF层维护最终一致性。
3.3 领域事件(Domain Event)
领域事件是聚合之间实现最终一致性的核心机制。当聚合根完成一次状态变更后,发布领域事件,其他聚合或BFF编排层订阅并响应。
- 定义:领域事件是“已经发生的事实”,使用过去时命名(如
OrderPlaced、PaymentReceived)。 - BFF中的用途:BFF层可以订阅领域事件,用于缓存失效、推送通知、跨聚合数据同步。
- 事件结构:通常包含事件ID、发生时间、聚合根ID、事件载荷(Payload)。
// BFF层订阅领域事件的典型代码结构
public class OrderPlacedEventHandler : IDomainEventHandler<OrderPlaced>
{
private readonly ICacheService _cache;
private readonly INotificationService _notification;
public async Task HandleAsync(OrderPlaced domainEvent)
{
// 1. 失效用户订单列表缓存
await _cache.InvalidateAsync($"user_orders_{domainEvent.UserId}");
// 2. 推送实时通知给前端
await _notification.SendAsync(domainEvent.UserId,
new OrderNotification(domainEvent.OrderId, "订单已创建"));
}
}
BFF事件设计警告:不要在BFF层直接发布领域事件。BFF应订阅后端领域层发布的事件,而非主动发布。BFF的职责是“编排与适配”,不是“领域决策”。领域事件的发布权应保留在核心领域层。
3.4 限界上下文(Bounded Context)
限界上下文是DDD中最关键的战术模式,它定义了模型边界和团队边界。每个限界上下文拥有独立的领域模型、数据库和术语表。
| 限界上下文 | 核心模型 | BFF关注点 |
|---|---|---|
| 订单上下文 | 订单、订单项、物流单 | 订单状态流转、物流追踪 |
| 支付上下文 | 支付单、退款单、账户 | 支付状态、退款进度 |
| 库存上下文 | 库存、仓库、SKU | 库存实时查询、预占 |
| 用户上下文 | 用户、权限、偏好 | 登录态、用户信息聚合 |
在BFF架构中,每个BFF服务通常对应一个或多个限界上下文的编排层。BFF不应跨度过大,否则会退化为传统的“大后端”。
3.5 六大构造块在BFF中的协作关系
在BFF架构实践中,这六大构造块并非孤立存在,而是形成一套完整的建模协作体系:
- 限界上下文划定BFF的职责范围,避免BFF变成“上帝服务”。
- 聚合根作为BFF API端点的核心操作单元,每个端点对应一个聚合根方法。
- 实体和值对象构成聚合的内部结构,BFF负责将它们组装为前端友好的视图模型。
- 领域事件驱动BFF的跨聚合数据同步和缓存更新,保持最终一致性。
BFF聚合根设计黄金法则:一个BFF端点 = 一个聚合根操作 + 零或多个领域事件订阅。如果发现一个端点需要操作两个不同的聚合根,说明该端点可能跨越了限界上下文边界,应拆分为两个独立的BFF端点或引入编排层。