DDD(领域驱动设计)的整洁架构(Clean Architecture)是一种通过分层和依赖规则,确保领域模型(业务逻辑)与技术实现解耦的架构模式。其核心目标是让业务逻辑成为系统的核心,而技术细节(如数据库、框架、UI)成为可替换的“插件”。
整洁结构如何帮助团队专注于领域模型,减少外部变化的影响,提升软件质量。
一、核心原则
-
分层架构
代码按职责分为多层(如接口层、应用层、领域层、基础设施层),确保各层职责明确。 -
依赖规则
外层依赖内层,内层不感知外层。例如:领域层不依赖基础设施层,但基础设施层可以实现领域层定义的接口。 -
领域模型为核心
领域层(Domain Layer)是核心,包含业务实体、规则和领域服务,与技术无关。 -
技术细节可替换
数据库、框架等实现细节放在外层(如基础设施层),可随时替换而不影响业务逻辑。
二、整洁架构示意图
三、举例说明-电商订单系统
1. 接口层(Interface Layer)
-
职责:处理外部输入(如 HTTP 请求、消息队列事件),将输入转换为领域层可理解的格式。
-
示例:
// OrderController.java(接口层)
@RestController
public class OrderController {
private final OrderService orderService;
// 依赖注入应用层服务
public OrderController(OrderService orderService) {
this.orderService = orderService;
}
@PostMapping("/orders")
public ResponseEntity<OrderDTO> createOrder(@RequestBody CreateOrderRequest request) {
// 将 HTTP 请求转换为应用层命令
CreateOrderCommand command = new CreateOrderCommand(request.getUserId(), request.getItems());
Order order = orderService.createOrder(command);
return ResponseEntity.ok(OrderDTO.fromDomain(order));
}
}
2. 应用层(Application Layer)
-
职责:协调领域对象和基础设施,实现用例流程,不包含业务规则。
-
示例:
// OrderService.java(应用层)
public class OrderService {
private final OrderRepository orderRepository;
private final PaymentGateway paymentGateway;
// 依赖基础设施接口(如 OrderRepository)
public OrderService(OrderRepository orderRepository, PaymentGateway paymentGateway) {
this.orderRepository = orderRepository;
this.paymentGateway = paymentGateway;
}
public Order createOrder(CreateOrderCommand command) {
// 调用领域层逻辑
Order order = Order.create(command.getUserId(), command.getItems());
// 协调支付等外部服务
paymentGateway.processPayment(order.getTotalAmount());
// 调用基础设施层保存订单
orderRepository.save(order);
return order;
}
}
3. 领域层(Domain Layer)
-
职责:定义业务实体、值对象、领域服务,包含核心业务规则。
-
示例:
// Order.java(领域层)
public class Order {
private OrderId id;
private UserId userId;
private List<OrderItem> items;
private OrderStatus status;
// 领域方法:创建订单的业务规则
public static Order create(UserId userId, List<OrderItem> items) {
if (items.isEmpty()) {
throw new IllegalArgumentException("订单必须包含商品");
}
Order order = new Order();
order.id = OrderId.generate();
order.userId = userId;
order.items = items;
order.status = OrderStatus.CREATED;
return order;
}
// 领域方法:订单状态流转规则
public void markAsPaid() {
if (this.status != OrderStatus.CREATED) {
throw new IllegalStateException("只有已创建的订单可标记为已支付");
}
this.status = OrderStatus.PAID;
}
}
4. 基础设施层(Infrastructure Layer)
-
职责:实现技术细节(如数据库操作、第三方服务调用),依赖领域层接口。
-
示例:
// JpaOrderRepository.java(基础设施层)
public class JpaOrderRepository implements OrderRepository {
private final OrderJpaRepository jpaRepository;
// 实现领域层定义的 OrderRepository 接口
@Override
public void save(Order order) {
OrderEntity entity = OrderEntity.fromDomain(order);
jpaRepository.save(entity);
}
}
// PaymentGatewayImpl.java(基础设施层)
public class PaymentGatewayImpl implements PaymentGateway {
@Override
public void processPayment(BigDecimal amount) {
// 调用第三方支付 API
ThirdPartyPaymentClient.process(amount);
}
}
四、关键优势
-
业务逻辑与技术解耦
领域层不依赖具体数据库或框架,可独立测试和演进。例如,更换数据库只需修改基础设施层。 -
可维护性
新增功能时,只需关注领域层的业务规则,无需修改技术实现。 -
清晰的依赖方向
依赖始终向内指向领域层,避免循环依赖。
DDD 的整洁结构通过分层和依赖倒置,让业务逻辑成为系统的核心,技术实现成为可插拔的细节。这种设计尤其适合复杂业务系统,能够显著提升代码的可维护性和扩展性。