DDD的分层架构是怎么样的?

领域驱动设计(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               // 命令行接口

各层交互流程(以创建订单为例)

  1. 用户接口层 接收HTTP请求,将JSON转换为CreateOrderCommand
  2. 应用层 调用OrderApplicationService
    • 创建Order聚合根。
    • 调用order.addItem()添加商品项。
    • 调用仓储保存订单。
    • 发布OrderCreatedEvent
  3. 领域层 执行核心业务逻辑:
    • Order聚合根校验状态和商品数量。
  4. 基础设施层
    • JpaOrderRepositoryOrder持久化到数据库。
    • KafkaEventPublisher将事件发送到消息队列。

分层架构的优势

  1. 高内聚低耦合:领域层与技术实现解耦。
  2. 可测试性:领域层可脱离框架单独测试。
  3. 适应变化:技术栈替换(如数据库从MySQL切到MongoDB)只需修改基础设施层。
  4. 清晰的职责划分:避免代码混杂(如业务逻辑侵入Controller)。

常见误区与解决方案

误区 解决方案
业务逻辑泄露到应用层或Controller 将逻辑内聚到领域对象(充血模型)。
领域层依赖Spring/JPA 通过依赖倒置,领域层仅定义接口。
基础设施层直接依赖领域层具体类 通过接口隔离,基础设施层实现领域层接口。

总结

DDD的分层架构通过领域层为核心,隔离技术与业务逻辑,确保软件的可维护性和扩展性。作为Java工程师,应重点关注:

  1. 领域层的纯粹性:避免技术框架污染领域模型。
  2. 依赖方向控制:通过接口和依赖倒置解耦各层。
  3. 代码结构清晰:模块化组织限界上下文(如每个上下文独立为子模块)。
相关推荐
洛神灬殇4 分钟前
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
数据库·redis·后端
雷渊37 分钟前
DDD经典的四层架构和洋葱架构、六边形架构区别
后端
SimonKing39 分钟前
【Spring Boot配置终极指南】1分钟让你精准指定配置文件,使应用部署游刃有余!
java·后端
雷渊39 分钟前
深入分析理解洋葱架构
后端
程序媛学姐1 小时前
SpringBoot Actuator健康检查:自定义HealthIndicator
java·spring boot·后端
程序媛学姐1 小时前
SpringBoot Actuator指标收集:Micrometer与Prometheus集成
spring boot·后端·prometheus
欲儿1 小时前
RabbitMQ原理及代码示例
java·spring boot·后端·rabbitmq
林 子1 小时前
Spring Boot自动装配原理(源码详细剖析!)
spring boot·后端
编程轨迹1 小时前
使用 Spring 和 Redis 创建处理敏感数据的服务
后端
未完结小说2 小时前
服务注册与发现(nacos)
后端