Java 项目结构与分层
源码目录约定与包分层:如何让依赖方向稳定、测试与部署边界清晰。
#type / concept
#status / growing
#tech / dev
#resource / java
[!info] 关联笔记
Java 项目结构与分层
这个概念为什么出现
语言会了仍可能把代码堆成“大泥球”。项目结构回答:源码放哪、测试放哪、依赖朝哪指、模块如何拆。
[!abstract] 一句话理解 采用构建工具约定目录;用包/模块表达边界;分层让依赖单向(入口→应用→领域→基础设施),避免基础设施细节污染领域。
最小可运行示例
场景:订单服务的包草图
src/main/java/shop/order/
api/OrderController.java # 入口适配
app/PlaceOrderService.java # 用例
domain/Order.java # 领域
infra/JdbcOrderRepository.java# 基础设施
src/test/java/shop/order/...
依赖方向:
api → app → domain
infra → domain(实现接口)
app → domain 接口(不直接依赖 JDBC 细节)
结合场景再看三个关注点
- 领域不依赖框架注解也可测(理想)。
- 接口定义在使用方/领域,实现放 infra。
- 测试镜像主包结构。
核心概念与准确模型
1. 标准目录
Maven/Gradle 默认 main/test 分离。
2. 分层 vs 按功能
- 按层:controller/service/repo 全局切
- 按功能:
order/下聚合层——扩展时常更清晰
3. 模块拆分
- 多模块:
order-domain/order-infra - 控制循环依赖
边界情况与反直觉行为
- 过度微服务拆分早于边界清晰。
- 共享 kernel 变成新泥球。
- 测试只测框架装配不测领域。
常见误区
[!warning] 常见误区:utils 包垃圾桶 无主名责任的 util 膨胀是架构腐烂信号。
工程实践
- ArchUnit 等守护依赖方向(可选)。
- 公共库慎抽。
- README 写清模块职责。
- 与团队统一一种主风格。
本节总结
- 目录约定 + 依赖方向
- 功能包 + 分层思想
- 为 Web/数据访问落地
自测题
- 为什么领域层不要直接依赖 JDBC 驱动类型?
- main/test 分离的收益?
参考答案
- 便于替换持久化与单测,避免基础设施细节泄漏。
- 生产产物不带测试代码,测试可依赖测试范围库。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| Maven Standard Directory Layout | 官方 | 目录约定 |
| Gradle Java projects | 官方 | 源集 |