刚学的时候照着教程写,包里就三个目录:
com.example.blog
├── controller 接收请求
├── service 业务逻辑
└── dao 数据库访问
能跑,但两三个月就乱了:DTO、VO、Entity 全塞在 entity 里,改一个字段要动五六个文件。
com.example.blog
├── BlogApplication.java
├── config/ 配置类:Web、Redis、安全
├── controller/ 只做参数校验和组装返回值
├── service/
│ ├── impl/ 实现
│ └── ... 接口
├── repository/ 数据访问(JPA 就是这层)
├── domain/
│ ├── entity/ 和表一一对应,不要再往外传
│ ├── dto/ 接收前端入参
│ └── vo/ 返回给前端
├── common/ 统一返回、异常、常量、工具
└── converter/ 实体与 VO 的转换
一、entity 不出层。 实体直接返回给前端,等于把表结构公开了。前端要什么字段,就在 VO 里挑。
二、controller 里不写 if-else。 参数校验用 @Valid + 注解,业务分支放 service。controller 控制在 20 行以内,超了就是逻辑写错地方了。
三、异常统一出口。 一个 @RestControllerAdvice 收口所有异常,返回统一结构:
{
"code": 40001,
"message": "文章不存在",
"data": null
}
前端就不用每个接口都判断一遍 HTTP 状态码了。
@Data
public class Result<T> {
private int code;
private String message;
private T data;
public static <T> Result<T> ok(T data) {
Result<T> r = new Result<>();
r.code = 0;
r.message = "ok";
r.data = data;
return r;
}
}
简单,但够用。真要上规模,错误码得按模块分段,不然几千个码很快就撞车。
见过把项目拆成七八个 Maven 模块的,api、core、common、infra、web……最后一个人维护,改个字段要跨三个模块编译。
一个人的项目,单模块 + 包分层就够了。 分层是为了让文件好找,不是为了架构图好看。