4.6、Repository模式实现
分类: DDD领域驱动设计实战
Repository 模式实现
Repository 模式是 DDD 中用于抽象数据访问的模式。它隔离了领域层和基础设施层,使领域模型不依赖于持久化技术。本节将学习如何实现 Repository 模式。
本节将学习:Repository 接口设计、仓储实现、数据转换,以及持久化抽象。
Repository 接口设计
接口定义
Repository 接口定义在领域层:
package com.example.ecommerce.domain.repository; import com.example.ecommerce.domain.model.Order; import java.util.Optional; public interface OrderRepository { void save(Order order); Optional<Order> findById(Long id); Optional<Order> findByOrderNo(String orderNo); void delete(Order order); }
仓储实现
基础设施层实现
Repository 实现在基础设施层:
package com.example.ecommerce.infrastructure.repository; import com.example.ecommerce.domain.model.Order; import com.example.ecommerce.domain.repository.OrderRepository; import com.example.ecommerce.infrastructure.persistence.OrderDO; import com.example.ecommerce.infrastructure.persistence.OrderMapper; import org.springframework.stereotype.Repository; @Repository public class OrderRepositoryImpl implements OrderRepository { private final OrderMapper orderMapper; private final OrderConverter converter; public OrderRepositoryImpl(OrderMapper orderMapper, OrderConverter converter) { this.orderMapper = orderMapper; this.converter = converter; } @Override public void save(Order order) { OrderDO orderDO = converter.toDO(order); if (order.getId() == null) { orderMapper.insert(orderDO); } else { orderMapper.updateById(orderDO); } } @Override public Optional<Order> findById(Long id) { OrderDO orderDO = orderMapper.selectById(id); return Optional.ofNullable(converter.toDomain(orderDO)); } }
数据转换
转换器实现
package com.example.ecommerce.infrastructure.converter; import com.example.ecommerce.domain.model.Order; import com.example.ecommerce.infrastructure.persistence.OrderDO; import org.springframework.stereotype.Component; @Component public class OrderConverter { public OrderDO toDO(Order order) { OrderDO orderDO = new OrderDO(); orderDO.setId(order.getId()); orderDO.setOrderNo(order.getOrderNo()); orderDO.setUserId(order.getUserId()); orderDO.setTotalAmount(order.getTotalAmount().getAmount()); orderDO.setStatus(order.getStatus().getCode()); return orderDO; } public Order toDomain(OrderDO orderDO) { if (orderDO == null) { return null; } Order order = new Order(); order.setId(orderDO.getId()); order.setOrderNo(orderDO.getOrderNo()); order.setUserId(orderDO.getUserId()); order.setTotalAmount(new Money(orderDO.getTotalAmount(), "CNY")); order.setStatus(OrderStatus.fromCode(orderDO.getStatus())); return order; } }
持久化抽象
抽象层设计
Repository 模式的优势:
- 领域层不依赖持久化技术
- 可以轻松切换持久化实现
- 便于测试(可以mock Repository)
官方资源
- DDD Repository 模式:https://www.domainlanguage.com/ddd/
本节小结
在本节中,我们学习了:
第一个是 Repository 接口设计。 在领域层定义接口。
第二个是仓储实现。 在基础设施层实现接口。
第三个是数据转换。 使用转换器进行领域对象和持久化对象的转换。
第四个是持久化抽象。 Repository 模式实现了持久化抽象。
这就是 Repository 模式实现。通过 Repository 模式,我们实现了领域层和基础设施层的解耦。
在下一节,我们将学习如何设计领域服务。