
DDD-029:遗留系统重构为 DDD 架构本章导读在实际工作中,我们经常面临维护和改进遗留系统的挑战。传统的贫血模型系统往往存在业务逻辑分散、代码难以维护、扩展困难等问题。本章将系统性地探讨如何将遗留系统渐进式地重构为 DDD 架构,重点介绍绞杀者模式、领域模型提取、数据库迁移等关键策略。学习目标理解遗留系统分析的方法和重构价值评估掌握绞杀者模式的核心原理和实施步骤学会渐进式重构的具体实践方法前置知识DDD 战略设计和战术设计基础重构基础概念和方法数据库迁移策略阅读时长约 50-60 分钟【原理】遗留系统重构策略一、遗留系统分析1.1 遗留系统的典型问题【历史架构问题】// ❌ 典型遗留系统:贫血模型 + 业务逻辑分散// Entity:只有数据,没有行为@Entity@Table(name="orders")publicclassOrderEntity{@IdprivateStringid;privateStringcustomerId;privateStringstatus;privateBigDecimaltotalAmount;// 只有 getter/setter,没有业务方法// 业务规则在哪里?}// Service:所有业务逻辑都在这里@ServicepublicclassOrderService{@AutowiredprivateOrderDaoorderDao;@AutowiredprivateProductDaoproductDao;@AutowiredprivateInventoryDaoinventoryDao;@AutowiredprivatePaymentServicepaymentService;@AutowiredprivateNotificationServicenotificationService;// 创建订单:业务逻辑散落在 Service 方法中publicStringcreateOrder(CreateOrderDTOdto){// 验证逻辑if(dto.getItems()==null||dto.getItems().isEmpty()){thrownewBusinessException("订单项不能为空");}// 计算逻辑BigDecimaltotal=BigDecimal.ZERO;for(OrderItemDTOitem:dto.getItems()){ProductEntityproduct=productDao.findById(item.getProductId());if(product==null){thrownewBusinessException("商品不存在:"+item.getProductId());}if(product.getStock()item.getQuantity()){thrownewBusinessException("库存不足:"+product.getName());}total=total.add(product.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())));}// 创建实体OrderEntityorder=newOrderEntity();order.setId(UUID.randomUUID().toString());order.setCustomerId(dto.getCustomerId());order.setStatus("CREATED");order.setTotalAmount(total);order.setCreatedAt(LocalDateTime.now());// 保存orderDao.insert(order);// 保存订单项for(OrderItemDTOitem:dto.getItems()){OrderItemEntityitemEntity=newOrderItemEntity();itemEntity.setOrderId(order.getId());itemEntity.setProductId(item.getProductId());itemEntity.setQuantity(item.getQuantity());orderItemDao.insert(itemEntity);}returnorder.getId();}// 支付订单:更多业务逻辑publicvoidpayOrder(StringorderId,PaymentRequestrequest){OrderEntityorder=orderDao.findById(orderId);if(order==null){thrownewBusinessException("订单不存在");}if(!"CREATED".equals(order.getStatus())){thrownewBusinessException("只有待支付订单才能支付");}// 调用支付PaymentResultresult=paymentService.pay(request);// 更新状态order.setStatus("PAID");order.setPaymentId(result.getPaymentId());order.setPaidAt(LocalDateTime.now())