DDD业务服务的目录规划

jonathan
2020-12-06 / 0 评论

DDD目录

DDD架构下的工程目录结构划分详解

在领域驱动设计(Domain-Driven Design, DDD)中,合理的工程目录结构对于实现复杂业务逻辑的清晰组织至关重要。本文将详细介绍基于DDD思想的工程目录划分方案,帮助开发团队更好地组织代码,提高系统的可维护性和可扩展性。

DDD工程目录的四层架构

根据思维导图所示,一个标准的DDD架构通常分为四个主要层次:

1. 接口层(interfaces)

接口层是系统与外部交互的门户,负责处理来自外部的请求,并将请求转发到应用层。

  • facade(统一对外接口):提供RESTful API接口,处理HTTP请求和响应
  • config(spring mvc相关配置):包含接口层相关的配置,如控制器配置、请求拦截器等
src/main/java/com/company/project/interfaces/
├── facade/          # 外观模式,统一接口
│   ├── dto/         # 数据传输对象
│   ├── assembler/   # DTO与领域对象转换
│   └── controller/  # 控制器
└── config/          # 接口层配置

2. 应用层(application)

应用层是业务流程的协调者,负责组织领域对象完成特定的应用功能。

  • service(应用服务接口和实现包):协调领域对象完成业务流程

  • assembler(DTO与Entity互相转换包):负责应用层与领域层数据模型的相互转换

  • event(事件发布/订阅)

    • publish(事件发布包):发布领域事件
    • subscribe(消息订阅包):订阅并处理领域事件
src/main/java/com/company/project/application/
├── service/         # 应用服务
│   ├── impl/        # 应用服务实现
│   └── dto/         # 应用服务数据传输对象
├── assembler/       # DTO与领域对象转换
└── event/           # 事件处理
    ├── publish/     # 事件发布
    └── subscribe/   # 事件订阅

3. 领域层(domain)

领域层是业务核心,包含业务规则和逻辑。

  • aggregate(聚合包)

    :聚合是一组关联的实体和值对象的集合

    • entity(聚合根、实体、值对象):领域模型核心元素
  • service(领域服务,处理特殊领域内业务):处理跨实体的业务逻辑

src/main/java/com/company/project/domain/
├── aggregate/       # 聚合
│   ├── order/       # 订单聚合(示例)
│   │   ├── Order.java           # 聚合根
│   │   ├── OrderItem.java       # 实体
│   │   ├── OrderStatus.java     # 值对象
│   │   └── OrderRepository.java # 仓储接口
│   └── user/        # 用户聚合(示例)
└── service/         # 领域服务
    └── impl/        # 领域服务实现

4. 基础设施层(infrastructure)

基础设施层为其他层提供技术支持。

  • repository(仓储数据库ORM层)

    • po(数据库对象):数据库表映射对象
    • assembler(entity转po):领域对象与数据库对象转换
  • domain.impl(领域服务实现包):领域服务的具体实现

  • config(基础配置):系统基础配置

  • utils(基础工具类):通用工具类

src/main/java/com/company/project/infrastructure/
├── repository/      # 仓储实现
│   ├── po/          # 持久化对象
│   ├── assembler/   # 领域对象与持久化对象转换
│   ├── mapper/      # MyBatis映射接口
│   └── impl/        # 仓储接口实现
├── domain/          # 领域层实现
│   └── impl/        # 领域服务实现类
├── config/          # 基础配置
└── utils/           # 工具类

目录结构的实践建议

  1. 按领域划分而非技术功能:在DDD中,首先应该按照业务领域进行划分,而非按照技术功能(如controller、service、dao等)
  2. 考虑限界上下文:不同的业务上下文应该有清晰的边界,可以在目录结构中体现
  3. 聚合根作为目录划分的基础:每个聚合根可以作为一个子目录,包含相关的实体和值对象
  4. 保持领域逻辑的纯净:领域层不应依赖其他层,特别是不应依赖基础设施层
  5. 接口与实现分离:定义清晰的接口,并将实现放在适当的包中

示例目录结构(电子商务系统)

src/main/java/com/ecommerce/
├── interfaces/
│   ├── facade/
│   │   ├── order/                  # 订单接口
│   │   └── product/                # 产品接口
│   └── config/                     # 接口配置
├── application/
│   ├── service/
│   │   ├── order/                  # 订单应用服务
│   │   └── product/                # 产品应用服务
│   ├── assembler/                  # DTO转换器
│   └── event/
│       ├── publish/                # 事件发布
│       └── subscribe/              # 事件订阅
├── domain/
│   ├── aggregate/
│   │   ├── order/                  # 订单聚合
│   │   ├── product/                # 产品聚合
│   │   └── user/                   # 用户聚合
│   └── service/                    # 领域服务
└── infrastructure/
    ├── repository/
    │   ├── po/                     # 持久化对象
    │   ├── assembler/              # 对象转换
    │   └── impl/                   # 仓储实现
    ├── domain/                     # 领域实现
    ├── config/                     # 系统配置
    └── utils/                      # 工具类

结语

DDD在项目中的应用还有待进一步验证,记录一下DDD业务服务的规划。

DDD

评论

博主关闭了当前页面的评论