DDD笔记

此篇内容为个人DDD笔记

1 DDD的核心思想

让软件的结构和领域模型对齐,使业务逻辑成为系统的核心

DDD强调:

  • 深入业务领域
  • 与领域专家协作
  • 建立反映业务本质的领域模型

2 DDD分层架构

DDD通常使用四层架构:

┌──────────────────────────────┐
│        API / UI 层(接口层) │ -> 提供外部接口,如 Web API、前端调用
├──────────────────────────────┤
│   应用层(Application Layer)│ -> 调用领域服务、协调流程、授权、事务管理
├──────────────────────────────┤
│      领域层(Domain Layer)  │ -> 系统核心业务模型(实体、聚合、服务、规则等)
├──────────────────────────────┤
│  基础设施层(Infrastructure)│ -> 技术细节实现,如数据库、消息队列、第三方接口
└──────────────────────────────┘

3 DDD术语详解

  1. 实体(Entity)
  • 有唯一标识(Id)
  • 生命周期长,状态可变
    示例:订单、用户、商品
public class Order
{
	public Guid Id { get; set; }
	public DateTime CreatedAt { get; set; }
}
  1. 值对象(Value Object)
  • 无标识(Id),只有值
  • 通常不可变(推荐使用record)
  • 相等性基于值比较
    示例:地址(国家、城市、街道)、金额(币种 + 数值)
public record Address(string Country, string City, string Street);
  1. 聚合根(Aggregate Root)

实体和子实体组成聚合(Aggregate),聚合根(AR)是聚合的代表
聚合:业务中相关实体和值对象的集合
聚合根:聚合的入口点,对外只暴露聚合根操作

  • 通过聚合根来操作整个聚合(Order控制OrderItem)
  • 聚合外部只能引用聚合根,不引用其子实体
    示例:Order是聚合根,OrderItem是其子实体
public class Order // 聚合根
{
	public Guid Id { get; private set; }
	public List<OrderItem> Items { get; private set; } = new();
	
	public void AddItem(Guid productId, int qty, decimal price)
	{
		Items.Add(new OrderItems(productId, qty, price));
	}
}
  1. 仓储(Repository)
  • 提供对象的持久化接口
  • 针对聚合根进行操作(保存、查找)
public interface IOrderRepository
{
	Task<Order?> GetByIdAsync(Guid id);
	Task AddAsync(Order order);
}
  1. 领域服务(Domain Service)

当业务行为不属于单个实体(如跨多个聚合),放到领域服务

  • 业务逻辑不适合放在实体中的“行为”
  • 无状态的业务逻辑操作类
public class OrderPricingService
{
	public decimal CalculateTotal(Order order)
	{
		//....
	}
}
  1. 应用服务(Application Service)

制作“业务用例协调”:调用领域层、聚合、仓储、服务等

  • 编排用户请求,调用领域对象/服务,完成业务用例
  • 不包含业务规则本身
// CQRS风格示例:
// 命令:
public record CreateOrderCommand(Guid CustomerId, List<CreateOrderItemDto> Items);
// 处理器:
public class CreateOrderCommandHandler : IRequestHandler<CreateOrderCommand,Guid>
{
	private readonly IOrderRepository _repo;
	public async Task<Guid> Handle(CreateOrderCommand request, CancellationToken cancellationToken = default)
	{
		var order = new Order(request.CustomerId);
		foreacch(var item in request.Items)
		{
			order.AddItem(item.ProductId, item.Quantity, item.Price);
		}
		
		await _repo.AddAsync(order);
		return order.Id;
	}
}
  1. 领域事件(Domain Event)

聚合内部某些行为完成后,发布领域事件->触发其他动作(通知、发货、积分等)

  • 聚合内部业务发生变化后的“事件通知”
  • 用于解耦逻辑,支持异步处理
// 定义事件:
public record OrderCreatedEvent(Guid OrderId, DateTime CreatedAt);

// 聚合中发布事件(通常结合Mediator):
public class Order
{
	public List<INotification> Events = new();
	public void Confirm()
	{
		Events.Add(new OrderCreatedEvent(Id, CreatedAt));
	}
}

// 处理器:
public class OrderCreatedEventHandler : INotificationHandler<OrderCreatedEvent>
{
	public Task Handle(OrderCreatedEvent notification, CancellationToken ct = default)
	{
		// ...
		return Task.CompletedTask;
	}
}
  1. 限界上下文(Bounded Context)
  • 大型系统的分割单位
  • 每个上下文都是独立模型、团队、数据库、接口
    示例:订单上下文、用户上下文、库存上下文

通常结合微服务设计,一个限界上下文即一个微服务
上下文之前通信方式:

  • API网关
  • 消息总线(Kafka,RabbitMQ)
  • 远程调用(gRPC)
  1. 防腐层(Anti-Corruption Layer, ACL)
  • 在保护领域模型不被其他系统/上下文“污染”
  • 适配外部系统数据结构->转为领域模型

4 DDD精神

简单释义
领域优先 从业务出发构建模型
语言统一 所有人员使用统一“通用语言(Ubiquitous Language)”
模型驱动设计 软件结构=业务模型
限界上下文 大系统拆分为多个模型独立的小系统

5 DDD构件关系图

            [ API / Application Layer ]
                     ↓
     ┌────────────Application Service────────────┐
     ↓                                             ↓
[Command] →→→→[ Domain Service ]←←→→[ Entity / Aggregate Root ] →→→ Events
                        ↓
                [ Value Objects ]
                     ↓
                [ Repository ]
                     ↓
        [ Infrastructure (EF, DB, MQ, etc.) ]
posted @ 2025-05-29 00:51  Ar4te  阅读(32)  评论(0)    收藏  举报