Files
global-coding-governance/java-coding-style/references/02-类型OOP与API设计.md
T
2026-07-25 23:45:09 +08:00

50 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 类型、OOP 与 API 设计
## 类型与相等性
- **必须**:包装类型使用 `equals``Objects.equals` 比较值,不使用 `==`;警惕缓存范围造成的偶然相等。
- **必须**`BigDecimal` 使用字符串或精确来源构造;数值大小用 `compareTo`,需要比较值与 scale 时才用 `equals`
- **必须**:货币、比例和计量值明确精度、舍入方式与单位;禁止用 `double` 承载精确金额。
- **必须**:重写 `equals` 时同时重写 `hashCode`,并验证对称性、传递性和集合行为。
- **推荐**:用领域类型、枚举和受约束构造器替代多个语义不明的 `String``int` 参数。
- **必须**:类型转换前检查范围和语义;不得以强制转换静默截断数值。
## 空值与返回值
- **必须**:明确参数与返回值的 nullability;不得依靠调用方猜测。
- **推荐**:返回空集合或空数组而非 `null`;不要为避免判断而创建语义虚假的空领域对象。
- **推荐**`Optional` 主要用于可能缺失的返回值;不要默认用于实体字段、DTO 字段、方法参数或集合元素。
- **必须**:禁止无条件链式解引用可能为空的对象;在边界校验或使用清晰分支表达缺失语义。
- **必须**:不要用断言校验外部输入,因为生产环境可能禁用断言。
- **推荐**:在系统边界尽早校验参数;项目支持 Bean Validation 时优先使用 `@Valid``@NotNull``@NotBlank``@Size` 等声明式校验。
- **推荐**:内部前置条件优先复用项目已有校验工具;只有需要定制业务错误码或分支处理时才手写空值判断。
- **必须**:不得仅为判空新增依赖。
- **推荐**:项目没有现成判空工具时,对象使用 `obj == null`,集合使用 `collection == null || collection.isEmpty()`Map 使用 `map == null || map.isEmpty()`;只有项目已经依赖 Apache Commons Collections 时,才使用 `CollectionUtils.isEmpty()``MapUtils.isEmpty()`
## OOP 与封装
- **必须**:遵循单一职责和最小可见性;字段默认 `private`,只暴露必要 API。
- **必须**:构造完成后对象应满足不变量;不要暴露可变内部集合、数组或日期对象。
- **推荐**:优先组合而非继承;继承只用于稳定的 is-a 关系和可替换契约。
- **必须**:覆写方法使用 `@Override`;可变参数只用于同类型、同语义参数,不使用 `Object...` 逃避类型设计。
- **必须**:构造器不得启动线程、访问远程资源或发布未完全构造的 `this`
- **推荐**:不可变对象优先;必要时使用 defensive copy,并确保集合元素也符合可变性预期。
- **推荐**:接口保持内聚,不创建囊括无关操作的“大而全” Service 或 Util。
## API 与兼容性
- **必须**:公共 API 明确输入校验、返回语义、错误模型、幂等性和副作用。
- **必须**:新增重载时检查 `null`、lambda、自动装箱和可变参数是否造成调用歧义。
- **必须**:修改 DTO、枚举、JSON 字段、RPC 签名或异常类型前评估调用方兼容性。
- **推荐**:返回接口类型而非具体集合实现;不要泄漏 ORM 实体、框架上下文或内部异常。
- **推荐**:避免布尔参数控制多个行为,优先使用有语义的方法、枚举或选项对象。
- **必须**:不得以反射、原始类型或未检查转换绕过编译器,除非边界隔离、理由明确并有测试。
## Lombok
- **必须**:仅在项目已采用 Lombok 时使用,不为风格统一单独引入依赖。
- **参考**DTO/VO 可使用 `@Data`;使用前检查可变性、相等性和敏感字段,存在特殊约束时改用明确的 `@Getter``@Setter``@EqualsAndHashCode``@ToString`
- **推荐**:实体类和值对象避免使用 `@Data`;按项目约定组合 `@Getter``@Setter``@Builder``@NoArgsConstructor``@AllArgsConstructor`,且不得绕过领域不变量或 ORM 构造约束。
- **推荐**:除非继承关系确有需要,不设置 `@EqualsAndHashCode(callSuper = true)`
- **必须**`toString` 不得暴露敏感字段,也不得触发懒加载或递归引用。