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层维护最终一致性。
聚合与聚合根边界示意图 聚合 A:订单聚合 聚合根:订单 (Order) 实体:订单项 (OrderItem) 值对象:收货地址 (Address) 聚合 B:用户聚合 聚合根:用户 (User) 实体:支付账户 (Account) 值对象:联系方式 (Contact) 通过 userId 引用 规则:外部只能通过聚合根(Order/User)访问内部对象;跨聚合通信使用领域事件

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不应跨度过大,否则会退化为传统的“大后端”。

BFF与限界上下文的关系 前端应用层(Web / Mobile / Desktop) BFF 编排层(按前端用例聚合) 订单上下文 Order Aggregate OrderItem Entity 支付上下文 Payment Aggregate Refund ValueObject 库存上下文 Inventory Aggregate Warehouse Entity 用户上下文 User Aggregate Profile ValueObject

3.5 六大构造块在BFF中的协作关系

在BFF架构实践中,这六大构造块并非孤立存在,而是形成一套完整的建模协作体系:

  1. 限界上下文划定BFF的职责范围,避免BFF变成“上帝服务”。
  2. 聚合根作为BFF API端点的核心操作单元,每个端点对应一个聚合根方法。
  3. 实体和值对象构成聚合的内部结构,BFF负责将它们组装为前端友好的视图模型。
  4. 领域事件驱动BFF的跨聚合数据同步和缓存更新,保持最终一致性。
BFF聚合根设计黄金法则:一个BFF端点 = 一个聚合根操作 + 零或多个领域事件订阅。如果发现一个端点需要操作两个不同的聚合根,说明该端点可能跨越了限界上下文边界,应拆分为两个独立的BFF端点或引入编排层。