架构师之路--领域驱动设计(DDD)实战指南(04)

张开发
2026/5/3 15:54:01 15 分钟阅读
架构师之路--领域驱动设计(DDD)实战指南(04)
系列导读本篇将深入讲解领域驱动设计的核心概念、战术设计与实战落地。文章目录一、DDD 概述1.1 什么是 DDD1.2 DDD 分层架构二、战略设计2.1 限界上下文2.2 上下文映射三、战术设计3.1 核心概念3.2 聚合设计原则四、代码实战4.1 实体定义4.2 值对象4.3 仓储接口4.4 领域服务4.5 应用服务总结一、DDD 概述1.1 什么是 DDD领域驱动设计是一种软件开发方法论强调以业务领域为核心进行软件设计。┌─────────────────────────────────────────────────────────────┐ │ DDD 核心思想 │ ├─────────────────────────────────────────────────────────────┤ │ 以领域为核心技术服务于业务 │ │ ️ 统一语言开发与业务使用相同术语 │ │ 限界上下文明确边界降低复杂度 │ │ 模型驱动代码即模型 │ └─────────────────────────────────────────────────────────────┘1.2 DDD 分层架构┌─────────────────────────────────────────────────────────────┐ │ 用户界面层 (UI) │ │ Controller / API │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ 应用层 (Application) │ │ Service / DTO / Assembler │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ 领域层 (Domain) │ │ Entity / Value Object / Repository │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ 基础设施层 (Infrastructure) │ │ Repository Impl / External Service │ └─────────────────────────────────────────────────────────────┘二、战略设计2.1 限界上下文概念说明领域业务问题空间子域领域的分解核心/支撑/通用限界上下文解决方案空间明确的边界2.2 上下文映射┌─────────────┐ ACL ┌─────────────┐ │ 订单上下文 │ ──────────► │ 库存上下文 │ └─────────────┘ └─────────────┘ │ │ │ OHS │ OHS ▼ ▼ ┌─────────────┐ ┌─────────────┐ │ 支付上下文 │ │ 物流上下文 │ └─────────────┘ └─────────────┘ ACL: 防腐层 OHS: 开放主机服务三、战术设计3.1 核心概念概念说明实体 (Entity)有唯一标识的对象值对象 (Value Object)无标识不可变聚合 (Aggregate)一组关联对象的集合领域服务不属于任何实体/值对象的操作仓储 (Repository)持久化抽象工厂 (Factory)复杂对象创建3.2 聚合设计原则1. 聚合根外部只能通过聚合根访问 2. 一致性边界聚合内保证强一致性 3. 小聚合聚合尽量小减少锁竞争 4. 通过 ID 引用聚合间通过 ID 关联四、代码实战4.1 实体定义// 订单聚合根EntityTable(namet_order)publicclassOrder{IdprivateOrderIdid;// 订单ID值对象privateCustomerIdcustomerId;// 客户IDprivateOrderStatusstatus;// 订单状态privateMoneytotalAmount;// 总金额值对象privateListOrderItemitems;// 订单项privateLocalDateTimecreateTime;// 业务方法添加订单项publicvoidaddItem(Productproduct,intquantity){if(status!OrderStatus.DRAFT){thrownewOrderOperationException(订单已提交无法添加商品);}OrderItemitemnewOrderItem(OrderItemId.generate(),product.getId(),product.getName(),product.getPrice(),quantity);items.add(item);recalculateTotal();}// 业务方法提交订单publicvoidsubmit(){if(items.isEmpty()){thrownewOrderOperationException(订单项不能为空);}this.statusOrderStatus.SUBMITTED;}// 业务方法取消订单publicvoidcancel(){if(statusOrderStatus.COMPLETED){thrownewOrderOperationException(已完成的订单无法取消);}this.statusOrderStatus.CANCELLED;}privatevoidrecalculateTotal(){this.totalAmountitems.stream().map(OrderItem::getSubtotal).reduce(Money.ZERO,Money::add);}}4.2 值对象// 金额值对象EmbeddablepublicclassMoneyimplementsSerializable{privateBigDecimalamount;privateStringcurrency;publicstaticfinalMoneyZEROnewMoney(BigDecimal.ZERO,CNY);publicMoneyadd(Moneyother){if(!this.currency.equals(other.currency)){thrownewIllegalArgumentException(币种不同无法相加);}returnnewMoney(this.amount.add(other.amount),this.currency);}publicMoneymultiply(intquantity){returnnewMoney(this.amount.multiply(BigDecimal.valueOf(quantity)),this.currency);}// 值对象必须实现 equals 和 hashCodeOverridepublicbooleanequals(Objecto){if(thiso)returntrue;if(!(oinstanceofMoney))returnfalse;Moneymoney(Money)o;returnamount.equals(money.amount)currency.equals(money.currency);}OverridepublicinthashCode(){returnObjects.hash(amount,currency);}}4.3 仓储接口// 仓储接口领域层publicinterfaceOrderRepository{OrderfindById(OrderIdid);voidsave(Orderorder);voiddelete(Orderorder);ListOrderfindByCustomerId(CustomerIdcustomerId);}// 仓储实现基础设施层RepositorypublicclassOrderRepositoryImplimplementsOrderRepository{AutowiredprivateOrderJpaRepositoryjpaRepository;AutowiredprivateOrderMapperorderMapper;OverridepublicOrderfindById(OrderIdid){OrderPOpojpaRepository.findById(id.getValue()).orElse(null);returnorderMapper.toDomain(po);}Overridepublicvoidsave(Orderorder){OrderPOpoorderMapper.toPO(order);jpaRepository.save(po);}}4.4 领域服务// 领域服务订单领域服务ServicepublicclassOrderDomainService{privatefinalOrderRepositoryorderRepository;privatefinalProductRepositoryproductRepository;/** * 创建订单 */publicOrdercreateOrder(CustomerIdcustomerId,ListOrderItemDTOitems){OrderordernewOrder(OrderId.generate(),customerId);for(OrderItemDTOitem:items){ProductproductproductRepository.findById(item.getProductId());order.addItem(product,item.getQuantity());}orderRepository.save(order);returnorder;}}4.5 应用服务// 应用服务ServiceTransactionalpublicclassOrderApplicationService{privatefinalOrderRepositoryorderRepository;privatefinalOrderDomainServiceorderDomainService;/** * 创建订单 */publicOrderDTOcreateOrder(CreateOrderCommandcommand){OrderorderorderDomainService.createOrder(command.getCustomerId(),command.getItems());returnOrderAssembler.toDTO(order);}/** * 查询订单 */publicOrderDTOgetOrder(StringorderId){OrderorderorderRepository.findById(newOrderId(orderId));if(ordernull){thrownewOrderNotFoundException(orderId);}returnOrderAssembler.toDTO(order);}}总结✅DDD 概述核心思想、分层架构✅战略设计限界上下文、上下文映射✅战术设计实体、值对象、聚合、仓储✅代码实战完整 DDD 代码示例下篇预告事件驱动架构设计与实现作者刘~浪地球系列架构设计四更新时间2026-04-09

更多文章