领域驱动设计(DDD)的分层架构旨在通过关注点分离 和职责明确来组织代码,使领域模型成为系统的核心,并隔离技术复杂性。以下是典型的分层架构及其职责,结合Java代码示例说明:
DDD分层架构(经典四层)
1. 用户接口层(User Interface Layer / Presentation Layer)
-
职责 :
- 处理用户输入(HTTP请求、命令行、消息队列等)。
- 返回响应(JSON、HTML等)。
- 不包含业务逻辑,仅负责输入/输出转换。
-
Java实现 :
java// 示例:Spring MVC的Controller @RestController @RequestMapping("/orders") public class OrderController { @Autowired private OrderApplicationService orderAppService; @PostMapping public ResponseEntity<Void> createOrder(@RequestBody CreateOrderRequest request) { // 1. 转换DTO为领域对象 CreateOrderCommand command = new CreateOrderCommand(request.getItems()); // 2. 调用应用服务 orderAppService.createOrder(command); return ResponseEntity.ok().build(); } }
2. 应用层(Application Layer)
-
职责 :
- 协调领域对象完成用例(如事务管理、权限校验)。
- 不包含核心业务逻辑,仅定义用例流程。
- 调用领域层的聚合根和领域服务。
-
Java实现 :
java@Service public class OrderApplicationService { @Autowired private OrderRepository orderRepository; @Autowired private EventPublisher eventPublisher; @Transactional public void createOrder(CreateOrderCommand command) { // 1. 创建聚合根 Order order = new Order(UUID.randomUUID().toString()); // 2. 调用领域对象方法 command.getItems().forEach(order::addItem); // 3. 持久化 orderRepository.save(order); // 4. 发布领域事件(跨聚合操作) eventPublisher.publish(new OrderCreatedEvent(order.getId())); } }
3. 领域层(Domain Layer)
-
职责 :
- 系统的核心,包含领域模型(实体、值对象、聚合根、领域服务)。
- 封装业务规则和不变条件。
- 不依赖任何其他层(完全独立于技术和框架)。
-
Java实现 :
java// 聚合根 public class Order { private String orderId; private List<OrderItem> items; private OrderStatus status; public void addItem(OrderItem item) { if (status != OrderStatus.DRAFT) { throw new IllegalStateException("Cannot modify a confirmed order"); } items.add(item); } public void confirm() { if (items.isEmpty()) throw new IllegalStateException("Empty order"); this.status = OrderStatus.CONFIRMED; } } // 领域服务(处理跨聚合逻辑) public class OrderValidationService { public void validateOrder(Order order) { // 复杂的业务规则校验 } }
4. 基础设施层(Infrastructure Layer)
-
职责 :
- 实现技术细节:数据库访问、消息队列、缓存、外部API调用等。
- 实现领域层的接口(如仓储接口)。
-
Java实现 :
java// 实现领域层的仓储接口(JPA) @Repository public class JpaOrderRepository implements OrderRepository { @Autowired private OrderJpaRepository jpaRepository; // Spring Data JPA接口 @Override public Order findById(String orderId) { OrderJpaEntity entity = jpaRepository.findById(orderId).orElseThrow(); return convertToDomain(entity); } // 省略转换逻辑 } // 消息队列实现(如Kafka) @Component public class KafkaEventPublisher implements EventPublisher { @Override public void publish(DomainEvent event) { kafkaTemplate.send("order-events", event); } }
分层依赖关系
-
单向依赖 :
用户接口层 → 应用层 → 领域层
基础设施层 → 领域层(通过依赖倒置原则,领域层定义接口,基础设施层实现接口)
-
关键原则:
- 领域层完全独立:不依赖Spring、JPA等技术框架。
- 避免基础设施层侵入领域模型:领域对象不包含JPA注解或框架依赖。
代码结构示例(Maven/Gradle项目)
plaintext
src/main/java
├── com.example
│ ├── application // 应用层
│ │ ├── OrderApplicationService.java
│ │ └── dto // DTO定义
│ ├── domain // 领域层
│ │ ├── model // 聚合根、实体、值对象
│ │ ├── service // 领域服务
│ │ ├── event // 领域事件
│ │ └── repository // 仓储接口(领域层定义)
│ ├── infrastructure // 基础设施层
│ │ ├── persistence // 数据库实现(JPA)
│ │ ├── messaging // 消息队列实现(Kafka)
│ │ └── rest // 外部API调用
│ └── interfaces // 用户接口层
│ ├── web // HTTP接口(Controller)
│ └── cli // 命令行接口
各层交互流程(以创建订单为例)
- 用户接口层 接收HTTP请求,将JSON转换为
CreateOrderCommand
。 - 应用层 调用
OrderApplicationService
:- 创建
Order
聚合根。 - 调用
order.addItem()
添加商品项。 - 调用仓储保存订单。
- 发布
OrderCreatedEvent
。
- 创建
- 领域层 执行核心业务逻辑:
Order
聚合根校验状态和商品数量。
- 基础设施层 :
JpaOrderRepository
将Order
持久化到数据库。KafkaEventPublisher
将事件发送到消息队列。
分层架构的优势
- 高内聚低耦合:领域层与技术实现解耦。
- 可测试性:领域层可脱离框架单独测试。
- 适应变化:技术栈替换(如数据库从MySQL切到MongoDB)只需修改基础设施层。
- 清晰的职责划分:避免代码混杂(如业务逻辑侵入Controller)。
常见误区与解决方案
误区 | 解决方案 |
---|---|
业务逻辑泄露到应用层或Controller | 将逻辑内聚到领域对象(充血模型)。 |
领域层依赖Spring/JPA | 通过依赖倒置,领域层仅定义接口。 |
基础设施层直接依赖领域层具体类 | 通过接口隔离,基础设施层实现领域层接口。 |
总结
DDD的分层架构通过领域层为核心,隔离技术与业务逻辑,确保软件的可维护性和扩展性。作为Java工程师,应重点关注:
- 领域层的纯粹性:避免技术框架污染领域模型。
- 依赖方向控制:通过接口和依赖倒置解耦各层。
- 代码结构清晰:模块化组织限界上下文(如每个上下文独立为子模块)。