MVC项目和DDD项目分层实践

52 阅读5分钟

一、MVC整体架构分层

image.png

src/main/java/com/yourcompany/yourproject/
├── common/               # 公共组件(工具类、常量、异常、基础实体等)
├── api/                  # 对外暴露接口(Controller 层 + DTO + VO)
├── service/              # 业务逻辑层(Service + Manager + Repository 实现)
└── start/                # 启动类 + 配置类

依赖方向(严格单向)

api → service → common
          ↑
        start (配置类可注入 service)

严禁反向依赖!

  1. service 层不能依赖 api;
  2. common 层不能依赖 service 或 api;
  3. start 层仅用于启动和配置,不包含业务逻辑;

1、common —— 公共层(基础能力复用)

所有模块均可依赖,不包含业务逻辑,只提供通用能力。

common/
├── constant/             # 常量类
│   └── StatusConstants.java
├── enums/                # 枚举类
│   └── OrderStatusEnum.java
├── exception/            # 统一异常处理
│   ├── BusinessException.java
│   └── GlobalExceptionHandler.java
├── utils/                # 工具类(静态方法,私有构造)
│   ├── DateUtils.java
│   └── BeanCopyUtils.java
├── base/                 # 基础类(如 BaseEntity、BaseVO)
│   └── BaseEntity.java
└── result/               # 统一返回格式
    └── Result.java

规范要点:

  1. 工具类必须是 static 方法,私有构造函数;
  2. 异常类继承 RuntimeException,命名清晰如 BusinessException;
  3. Result 类包含 code/msg/data,符合前后端约定;
  4. 不允许在公共层引用业务层代码;

2、 api —— 接口层(对外暴露的 HTTP API)

对应图中的“终端显示层”和“请求处理层(Web层)”,负责接收请求、参数校验、调用 Service、返回响应。

api/
├── web/                  # Web Controller
│   ├── order/
│   │   ├── OrderController.java
│   │   └── dto/
│   │       ├── OrderCreateRequest.java
│   │       └── OrderResponse.java
│   └── user/
│       └── UserController.java
├── vo/                   # 视图对象(View Object),用于前端展示
│   └── OrderVO.java
└── aspect/               # AOP 切面(如日志、权限校验)
    └── LogAspect.java

规范要点:

  1. Controller 类名以 Controller 结尾;
  2. DTO 命名清晰,如 OrderCreateRequest、OrderResponse;
  3. 使用 @RestController + @RequestMapping 注解;
  4. 参数校验使用 @Valid + @RequestBody;
  5. 不允许在 Controller 中写业务逻辑,仅做参数校验 + 调用 Service;
  6. 返回值封装为 Result<T>

3、 service —— 业务逻辑层(核心业务实现)

对应图中的“业务逻辑层(Service层)”、“通用处理层(Manager层)”、“数据持久层(DAO层)”,是 MVC 架构的核心。

目录结构:

service/
├── service/              # 业务服务层(对应 Service层)
│   ├── OrderService.java
│   └── UserService.java
├── manager/              # 通用处理层(对应 Manager层)
│   ├── CacheManager.java
│   └── ThirdPartyManager.java
├── repository/           # 数据访问层(对应 DAO层)
│   ├── OrderRepository.java
│   └── UserRepository.java
├── entity/               # 实体类(对应数据库表)
│   ├── Order.java
│   └── User.java
├── mapper/               # MyBatis 映射接口(若使用 MyBatis)
│   └── OrderMapper.java
└── impl/                 # 实现类(可选,若使用 JPA 可省略)
    └── OrderServiceImpl.java

规范要点:

  1. Service 类命名以 Service 结尾;
  2. Manager 类命名以 Manager 结尾,负责通用能力下沉(如缓存、第三方调用);
  3. Repository 接口命名以 Repository 结尾,实现类可加 Impl;
  4. Entity 类必须有 equals/hashCode 实现;
  5. 使用 @Transactional 控制事务边界;
  6. 不允许在 Service 层直接操作数据库,应通过 Repository;

4、 start —— 启动与部署层

包含启动类、配置类、健康检查、监控等,deploy 子目录用于存放部署脚本。

start/
├── Application.java      # Spring Boot 启动类
├── config/               # 配置类
│   ├── WebMvcConfig.java
│   ├── MyBatisConfig.java
│   └── SwaggerConfig.java
└── health/               # 健康检查
    └── HealthIndicator.java

规范要点:

  1. 启动类放在根包下,命名如 Application.java;
  2. 配置类加 @Configuration 注解;
  3. Bean 名称清晰,如 orderRepositoryBean;
  4. 避免在配置类中写业务逻辑;
  5. 使用 @Value 或 @ConfigurationProperties 注入配置;

二、DDD 整体架构分层(六层结构)

image.png

src/main/java/com/yourcompany/yourproject/
├── application          # 应用层(Application Layer)
├── domain               # 领域层(Domain Layer) ← 核心
├── infrastructure       # 基础设施层(Infrastructure Layer)
├── interfaces           # 接口层(Interface Layer)← 对外暴露的 API
├── common               # 公共层(Common Layer)
└── config               # 配置层(Config Layer)

依赖方向(严格单向)

interfaces → application → domain ← infrastructure
                             ↑
                           common

严禁反向依赖!

  1. domain 层不能依赖 application 或 interfaces;
  2. infrastructure 只能依赖 domain 和 common;
  3. application 依赖 domain 和 infrastructure;
  4. interfaces 依赖 application 和 common;

1、interfaces —— 接口层(对外暴露的 HTTP / RPC / MQ)

负责接收外部请求,调用应用服务,返回响应。不包含业务逻辑。

interfaces/
├── web/                  # Web 接口(Controller)
│   ├── order/
│   │   ├── OrderController.java
│   │   └── dto/
│   │       ├── OrderCreateRequest.java
│   │       └── OrderResponse.java
│   └── user/
│       └── UserController.java
├── rpc/                  # RPC 接口(如 Dubbo)
├── mq/                   # 消息监听器(如 Kafka/RocketMQ)
└── facade/               # 外部系统对接门面(可选)

规范要点:

  1. Controller 类名以 Controller 结尾;
  2. DTO 命名清晰,如 OrderCreateRequest、OrderResponse;
  3. 不允许在 Controller 中写业务逻辑,仅做参数校验 + 调用 Application Service;
  4. 使用 @RestController + @RequestMapping 注解;
  5. 参数校验使用 @Valid + @RequestBody;

2、application —— 应用层(Application Layer)

协调领域对象完成用例,不包含业务规则,只负责流程编排。

application/
├── service/
│   ├── OrderAppService.java        # 应用服务
│   └── UserAppService.java
├── command/                        # 命令对象(CQRS 可选)
│   └── CreateOrderCommand.java
├── event/                          # 应用事件(可选)
│   └── OrderCreatedEvent.java
└── dto/                            # 应用层 DTO(转换领域对象到接口层)
    └── OrderDTO.java

规范要点:

  1. 服务类命名以 AppService 或 Service 结尾;
  2. 方法名动词开头,如 createOrder, cancelOrder;
  3. 不直接访问数据库或第三方服务,通过 Domain + Infrastructure 实现;
  4. 使用 @Transactional 控制事务边界;
  5. 返回值封装为 Result<T>ResponseEntity<T>

3、domain —— 领域层(核心业务逻辑)

包含实体、值对象、聚合根、领域服务、领域事件、仓储接口等。

domain/
├── model/                # 领域模型(Entity, Value Object, Aggregate Root)
│   ├── order/
│   │   ├── Order.java            # 聚合根
│   │   ├── OrderItem.java        # 实体
│   │   └── OrderStatus.java      # 值对象
│   └── user/
│       └── User.java
├── service/              # 领域服务(无状态,跨聚合操作)
│   └── OrderDomainService.java
├── repository/           # 仓储接口(定义数据访问契约)
│   └── OrderRepository.java
├── event/                # 领域事件(如 OrderPaidEvent)
│   └── OrderPaidEvent.java
└── exception/            # 领域异常(自定义业务异常)
    └── OrderException.java

规范要点:

  1. 实体类继承 AbstractEntity 或实现 AggregateRoot 接口;
  2. 值对象不可变(final + 私有构造 + getter);
  3. 聚合根内方法封装业务规则(如 order.pay());
  4. 仓储接口不实现,由 Infrastructure 层实现;
  5. 异常命名清晰,如 OrderNotFoundException;
  6. 所有领域对象必须有 equals/hashCode 实现(阿里规范要求);

4、infrastructure —— 基础设施层(技术实现)

实现领域层定义的接口,如数据库访问、缓存、消息、外部系统调用等。

infrastructure/
├── persistence/          # 数据持久化实现
│   ├── jpa/
│   │   └── OrderJpaRepository.java
│   └── mybatis/
│       └── OrderMapper.java
├── cache/                # 缓存实现
│   └── RedisOrderCache.java
├── message/              # 消息发送/接收实现
│   └── KafkaOrderProducer.java
├── external/             # 外部系统适配器
│   └── PaymentGatewayAdapter.java
└── repository/           # 仓储实现
    └── OrderRepositoryImpl.java

规范要点:

  1. 实现类命名以 Impl 结尾(如 OrderRepositoryImpl);
  2. 使用 @Repository 注解标记 DAO 层;
  3. SQL 映射文件放在 resources/mapper/ 下;
  4. 避免在基础设施层写业务逻辑;
  5. 使用 @Component 或 @Service 注入依赖;

5、common —— 公共层(工具、常量、基础类)

提供全局通用组件,如工具类、枚举、基础实体、统一异常处理等。

common/
├── constant/             # 常量类
│   └── OrderConstants.java
├── enums/                # 枚举类
│   └── OrderStatusEnum.java
├── utils/                # 工具类
│   └── DateUtils.java
├── exception/            # 全局异常处理
│   └── GlobalExceptionHandler.java
├── base/                 # 基础类(如 BaseEntity)
│   └── BaseEntity.java
└── result/               # 统一返回格式
    └── Result.java

规范要点:

  1. 工具类必须是 static 方法,私有构造函数;
  2. 枚举类命名清晰,如 OrderStatusEnum;
  3. 异常处理使用 @RestControllerAdvice + @ExceptionHandler;
  4. Result 类包含 code/msg/data,符合前后端约定;
  5. 不允许在公共层引用业务层代码;

7、config —— 配置层(Spring 配置类)

包含 Bean 配置、拦截器、过滤器、Swagger、MyBatis、Redis 等配置。

config/
├── WebMvcConfig.java
├── MyBatisConfig.java
├── SwaggerConfig.java
├── RedisConfig.java
└── TransactionConfig.java

规范要点:

  1. 配置类加 @Configuration 注解;
  2. Bean 名称清晰,如 orderRepositoryBean;
  3. 避免在配置类中写业务逻辑;
  4. 使用 @Value 或 @ConfigurationProperties 注入配置;