基本代码规范
本篇约定 ecshopx-java 共享代码的基本元素,确保多 Bundle 间技术互通。能愿动词(必须、应该、禁止等)含义与 RFC 2119 一致。
1. 包与模块
- 每个业务域 必须 对应独立 Maven 模块
ecshopx-<domain>; - Java 根包 必须 为
cn.shopex.ecshopx.<domain>,与模块名<domain>一致; - 公共能力放在
ecshopx-common、ecshopx-dispatch等基础模块,禁止 在业务 Bundle 内复制实现; - 源文件 必须 使用 UTF-8 编码(无 BOM)。
2. 分层
| 层级 | 包 | 职责 |
|---|---|---|
| API | api.admin.v1 / api.front.v1 | HTTP 适配、鉴权、响应封装 |
| Service | service | 业务编排、事务边界 |
| Repository | repository(可选) | 可复用查询封装 |
| Mapper | mapper | MyBatis-Plus 数据访问 |
| Domain | domain | 表映射实体 |
禁止 上层跳过 Service 直接调用下层以外的持久化;禁止 Bundle A 直接 import Bundle B 的 mapper / domain。
3. 命名
- 类名:大驼峰(
StudlyCaps),如ItemsController、OrderCreatePersistencePortImpl; - 方法名:小驼峰,动词或动宾短语,如
getByItemIdAndCompany; - 常量:全大写下划线分隔,如
MAX_RETRY_COUNT; - 包名:全小写,无下划线,如
cn.shopex.ecshopx.orders.service.front.wxapp。
4. 空指针与 Optional
- 对可能为 null 的返回值,在 Service / Repository 边界 明确约定:返回空集合优于 null,或文档化 null 语义;
- 集合遍历、链式调用前 应该 做 null 检查或使用
Objects.requireNonNull(仅用于真正不可为 null 的契约); - 避免在 Controller 层散落
if (x == null)业务分支,应收拢到 Service; - 数据库
SUM等聚合 可能 返回 null,参考 MySQL 规范 使用IFNULL或 Java 侧默认值。
5. 日志
- 使用 SLF4J(
private static final Logger log = LoggerFactory.getLogger(...)或 Lombok@Slf4j); - 错误 级别记录异常栈:
log.error("op failed, orderId={}", orderId, e); - 禁止 在日志中输出密码、完整 JWT、
secret-key等敏感配置; - 调试信息用
debug,生产默认可关闭;高频路径避免info打印大对象 JSON。
6. 文件与副作用
- 一个
.java文件 应该 只承载一个 public 顶层类(内部类除外); - 配置类、启动类除外,避免 在类加载时产生副作用(静态块改全局状态、随意
System.out)。
7. 依赖与注入
- 推荐 构造器注入(
@RequiredArgsConstructor+final字段),便于测试; - 跨模块依赖 必须 面向 Port 接口(
ecshopx-common或领域 Port),实现类放在integration/openapi。
