cursor中使用效果:
在这里插入图片描述

阿牛规范(Java 后端)

规则文件.cursor/rules/drin.rule.mdc(别名 drin.rule)。本规范以《阿里巴巴 Java 开发手册》v1.4.0 为基底并叠加 tc-fms 项目条款;原手册 PDF 可参考 docs/阿里巴巴Java开发...1528268103.pdf

对 AI 的约束(代码生成须遵守)

  • 在本项目中编写、修改或生成任何 Java 代码,以及与之配套的 SQL、MyBatis XML、日志与异常处理时,必须遵守本文件中的规约。
  • 全文应用:当用户或任务明确要求遵循 阿牛规范 / drin.rule 时,须将本文件全部章节(含【强制】/【推荐】/【参考】及「附:与 tc-fms 项目对齐」)一并执行,不得只摘取部分条文。
  • 优先级AGENTS.md / framework.mdc 中的 tc-fms 专规(分层、模块、Java 8、BeanUtils 等)优先;本规约作为阿牛规范通用补充;二者冲突时以项目专规为准。
  • 执行尺度:【强制】级别必须满足;【推荐】级别在无充分理由时不应忽略;【参考】级别按场景采纳。

条文分级:规约分 【强制】/【推荐】/【参考】 三级。
与本项目关系:tc-fms 的分层、模块依赖、Java 8 语法、BeanUtils、ResponseDTO 等以 AGENTS.md / framework.mdc 为准;本文件用于对齐工程与编码习惯并收录 tc-fms 专项补充。


一、编程规约

(一)命名风格

  • 【强制】 命名不得以下划线或美元符号开始或结束(反例:_name$namename_)。
  • 【强制】 禁止拼音英文混用、禁止中文命名;国际通用词(如 alibaba、taobao)可视同英文。
  • 【强制】 类名 UpperCamelCase;例外后缀:DO/BO/DTO/VO/AO/PO/UID 等(正例:UserDOXmlService)。
  • 【强制】 方法名、参数名、成员变量、局部变量一律 lowerCamelCase
  • 【强制】 常量全大写,单词间下划线,语义完整(正例:MAX_STOCK_COUNT;反例:MAX_COUNT)。
  • 【强制】 抽象类以 AbstractBase 开头;异常类以 Exception 结尾;测试类以被测类名开头、Test 结尾。
  • 【强制】 数组:int[] arrayDemo,禁止 String args[]
  • 【强制】 POJO 中布尔类型不要is 前缀(避免序列化/RPC 解析异常);基本类型 Boolean isDeletedisDeleted() 组合尤其要避免。
  • 【强制】 包名全小写,点分隔符间仅一个英文单词;包名单数;类名可有复数含义。
  • 【强制】 禁止不规范缩写(反例:AbsClasscondi)。
  • 【推荐】 命名用完整单词组合;自定义元素能自解释。
  • 【推荐】 使用设计模式时,类名体现模式(正例:OrderFactoryLoginProxy)。
  • 【推荐】 接口方法、属性不加多余修饰符(含 public);接口内变量若必须,应为与接口方法相关的基础常量。
  • 【强制】 Service/DAO:对外暴露接口,实现类后缀 Impl(正例:CacheServiceImpl 实现 CacheService)。
  • 【推荐】 表能力接口可用形容词形式(如 -able),AbstractTranslator 实现 Translatable
  • 【参考】 枚举类名建议 XxxEnum,成员全大写下划线。
  • 【参考】各层方法命名
    • 单个对象:get 前缀;多个:list 前缀且表复数,如 listObjects;统计:count;插入:save/insert;删除:remove/delete;修改:update
    • 领域模型:xxxDO(表)、xxxDTOxxxVO;统称 POJO,禁止命名为 xxxPOJO
  • 【推荐】(tc-fms)Map 变量命名:建议采用 {键语义}K{值语义}Pair 形式(中间的 K 为固定分隔,读作「键到值」,不是泛型尖括号),整体以 Pair 结尾,一眼可辨「键—值」映射,避免与 List、单个实体变量混淆。正例:Map<Long, User> userIdEntityPair(键为用户 ID,值为用户实体);Map<String, Integer> codeCountPair。键或值语义较长时可适度缩写,须保持 lowerCamelCase 可读;避免主名使用无含义的 mapdatatemp 等。若存量代码已采用团队共识且表意清晰的 xxxByYyyxxxToYyy 等命名,可延续,新增代码优先本约定。

(二)常量定义

  • 【强制】 禁止魔法值直接出现在代码中。
  • 【强制】 long/Long 赋值数字后加大写 L,禁止小写 l(易与 1 混淆)。
  • 【推荐】 常量按功能归类,避免一个常量类容纳一切。
  • 【推荐】 常量复用层次:跨应用 → 二方库 constant;应用内 → 一方模块 constant;子工程、包内、类内各层明确,避免两处定义同义不同值。
  • 【推荐】 固定范围内取值用 enum
  • 【推荐】(tc-fms)枚举优先于零散静态常量:有限、封闭取值优先enum 表达,扩展性、可读性、与 switch/映射配合通常优于分散的 public static final优先复用系统或模块内已有枚举,禁止重复新建同义枚举造成多处维护。

(三)代码格式

  • 【强制】 空块写 {};非空块:左大括号前不换行、后换行;右大括号前换行;与 else 连写时右大括号后不换行;终止的右大括号后换行。
  • 【强制】 小括号与字符间无空格;左大括号前须空格;if/for/while/switch/do 与括号间须空格。
  • 【强制】 二目、三目运算符左右各一空格。
  • 【强制】 4 空格缩进,禁止 Tab(若用 Tab 须设为 4 空格且勿勾选“使用 Tab 字符”类选项)。
  • 【强制】 注释 // 后空一格再写内容。
  • 【强制】 单行不超过 120 字符;换行时次行相对首行缩进 4 空格,第三行起不再额外缩进;运算符、方法调用的点与下文一起换行;多参数在逗号后换行;勿在括号前换行。
  • 【强制】 方法参数定义与调用:逗号后必须空格。
  • 【强制】 文件编码 UTF-8;换行符 Unix(LF)。
  • 【推荐】 单方法总行数(含签名、注释、空行)不超过 80;共性逻辑抽取方法。
  • 【推荐】 勿用空格对齐多行赋值;不同逻辑间一空行分隔。
  • 【推荐】(tc-fms)静态导入:对纯工具类的静态方法(如 com.tc.fms.common.utils.collection.CollectionUtilsorg.springframework.util.StringUtilsorg.apache.commons.lang3.StringUtils 等),优先使用 import static 包.类.方法名import static 包.类.*,在代码中省略类名前缀以缩短调用;与当前类/父类方法或其它静态导入同名冲突,或静态导入过多导致来源不清,则保留 类名. 限定。

(四)OOP 规约

  • 【强制】 静态成员用类名访问,勿用实例引用。

  • 【强制】 覆写方法必须 @Override

  • 【强制】 可变参数:相同类型、相同业务含义才可用;参数放最后;尽量不用可变参数。

  • 【强制】 外部已调用的接口不得改方法签名;过时须 @Deprecated 并说明替代接口/服务。

  • 【推荐】(tc-fms)废弃公共 API:对仍有调用方的公共类/方法/接口,勿直接删除;须先标注 @Deprecated,在 Javadoc 中写明替代方式预计移除时间,经若干版本观察后再删除,避免破坏依赖方构建。

  • 【强制】 禁止使用过时的类/方法;调用方有义务确认新实现。

  • 【强制】 equals:用常量或确定非空对象调用,或 Objects.equals(JDK7+)。

  • 【强制】 包装类型比较一律 equals(注意 Integer 缓存区间与堆对象区别)。

  • 【强制】 POJO 属性用包装类型;RPC 入参/返回值用包装类型;局部变量推荐基本类型。

  • 【强制】 DO/DTO/VO 等 POJO 不要设属性默认值。

  • 【强制】 序列化类增属性慎改 serialVersionUID;不兼容升级再改并知会。

  • 【强制】 构造方法内禁止业务逻辑;初始化放 init 等。

  • 【强制】 POJO 须 toString;继承时注意 super.toString

  • 【强制】 禁止同一属性同时存在 isXxx()getXxx()

  • 【推荐】 String.split 后数组访问注意尾部分隔符与 IndexOutOfBoundsException

  • 【推荐】 重载构造/同名方法按序放在一起;类内方法顺序:公有/保护 → 私有 → getter/setter。

  • 【推荐】 工具类须以 JDK 为主实现**:纯工具类(如 final 类、私有构造、仅提供静态方法的辅助类)在编写其方法体时,使用 JDK 标准库java.langjava.utiljava.timejava.nio 等)实现可由 JDK 直接完成的等价能力,禁止在无正当理由时为图省事而直接调用 Hutool、Apache Commons、Guava 等第三方工具库替代上述能力,以保障可移植性并控制传递依赖与版本冲突面。例外(须在类或方法 Javadoc 中说明理由):JDK 无等价 API;或经评审确认采用 JDK 手写后在正确性、性能或可维护性明显劣于某第三方 API。与业务层专规的关系:本条仅约束工具类自身源码业务代码(Domain、API 等)仍遵循「集合处理」等对项目 CollectionUtils、Hutool 等的约定,二者分层适用、不互相替代

  • 【推荐】(tc-fms)抽取方法时的入参:将重复逻辑拆成私有方法或包内辅助方法时,优先传入聚合对象(如入参 XxxDTO、领域实体、或专责承载多字段的「命令/参数」小对象),在方法体内再访问属性;避免把同一来源对象的多个 obj.getFoo()obj.getBar() 拆成一长串基本类型或零散形参。尽量减少参数个数,避免同源、同批次的 5 个以上字段平铺成参表;若字段本就属于同一 DTO/实体,直接传该对象即可。例外:跨层纯工具、与类型解耦的算法、或确无合适载体时,可保留少量标量;若新增字段,优先扩展被传对象而非加长参数列表。

  • 【推荐】(tc-fms)对外方法形参个数一般以不超过 3 个为宜;若继续增长,宜封装为 Query/Command/Context 等聚合对象,与上条「优先传聚合对象」一致,避免「参数表」过长难以阅读与演进。

  • 【推荐】(tc-fms)可复用的公共能力:对同一语义、多种入参组合的场景,优先通过方法重载接口抽象统一参数对象(如配置类、选项类)表达,避免大量仅参数不同的平行方法名。

  • 【推荐】(tc-fms)对象装配与转换:在符合分层与 BeanUtils 专规的前提下,链式 get/set 过长时,优先使用构造方法静态工厂或 Builder,缩短主流程中的样板代码;禁止在 Controller 等上层堆叠大量手写映射。

  • 【推荐】 循环内字符串拼接用 StringBuilder#append

  • 【推荐】 final:不可继承类、不可变引用、不可重写方法、POJO setter 可 final、循环内复用变量等场景。

  • 【推荐】 慎用 Object#clone(默认浅拷贝)。

  • 【推荐】 访问控制从严:工具类无 public 构造、成员尽量 private、按需 protected。

  • 【强制】(tc-fms)泛型(Java 8)禁止无正当理由使用原始类型(raw type),变量、参数、返回值、字段及面向对象协作处须写出完整、必要的泛型实参或通配符(如 List<String>List<?>),不得写成裸 List;在赋值右侧、new 构造、方法调用链中凡编译器已能推断类型参数时,须使用 diamond <>(如 List<String> list = new ArrayList<>();Map<String, Object> m = new HashMap<>();),避免<> 内重复书写可由左侧或上下文推断的冗余类型实参。与 JDK/第三方遗留 API 交互且无法改写签名时,原始类型仅在局部、加注释前提下可例外。

(五)集合处理

  • 【强制】 重写 equals 必须重写 hashCodeSet 元素、Map 的 key 为自定义对象时须正确实现二者。
  • 【强制】 ArrayList#subList 结果不可强转为 ArrayList;勿在 subList 场景下对原集合结构增删导致子列表遍历异常。
  • 【强制】 Collection#toArray(T[]) 传入类型一致、大小为 list.size();避免无参 toArray() 再强转。
  • 【强制】 Arrays.asList 转出的列表不可 add/remove/clear;注意底层仍是数组,改数组会影响视图。
  • 【强制】 泛型 <? extends T> 不可随意 add<? super T> 使用注意 PECS(Producer Extends Consumer Super)。
  • 【强制】 foreach 中不要 remove/add;用 Iterator.remove,并发时对迭代器加锁。
  • 【强制】 Comparator 须满足自反、传递、与相等一致,否则 Arrays.sort/Collections.sort 可能 IllegalArgumentException
  • 【推荐】 JDK7+ 使用 diamond;集合初始化指定容量(如 HashMap 按元素数/负载因子估算)。
  • 【推荐】 Map 遍历用 entrySet,少用 keySet 二次查找;JDK8 可用 Map.forEach
  • 【推荐】 注意各 Map 实现是否允许 null 键值(如 ConcurrentHashMap 不可 null)。
  • 【参考】 利用 Set 去重,避免 List + contains 暴力去重。
  • 【强制】(tc-fms)业务代码(Domain、API、ORM Service 实现等)禁止Collection / List / Set 等直接编写 stream()parallelStream() 及流式链(如 map / filter / collect / groupingBy)完成映射、过滤、分组、去重等;须优先在 com.tc.fms.common.utils.collection.CollectionUtils 中选用已有方法(如 convertListconvertMapfilterListconvertMultiMap 等)。若无合适方法,应在该工具类中新增静态方法统一封装,实现可采用 Stream 或普通循环,但入口必须集中;新方法须对 集合为 null、空集合、元素为 null 等边界与空指针风险做一致约定与防护(与现有工具方法风格对齐),避免在业务类中散落 NPE 隐患。
  • 【推荐】(tc-fms)将 MyBatis-Plus IPage<实体> 转为 IPage<VO/DTO> 时,统一使用 com.tc.fms.common.utils.collection.CollectionUtils#convertPage,在转换函数中完成单条 Entity → VO 映射;由工具方法统一拷贝 currentsizetotalpagesrecords,避免手写 new Page 或仅 convert 导致分页元数据遗漏、空页 total 丢失或与源页不一致。
  • 【推荐】(tc-fms)将 Map<K, V>value 统一映射为另一类型得到 Map<K, R>(key 不变)时,优先使用 CollectionUtils#convertMapValue;若 valueList 且需对列表元素批量转换,可查 convertMapValues 等同类方法,避免在业务类中手写循环逐个 put。须注意:convertMapValue单次映射结果为 null 时会跳过该键;若业务必须保留「值为 null」的条目,应显式处理或扩展工具方法。
  • 【推荐】(tc-fms)集合是否为空/非空、字符串是否为空/空白以及列表构造、合并、切片等常用操作,优先使用 Hutool:cn.hutool.core.collection.CollUtil(及按需 ListUtilSetUtil 等)与 cn.hutool.core.util.StrUtil,统一空安全与习惯用法,避免散落手写 == null、裸 length() == 0、重复 trim() 等易错写法。若语义已由本项目 CollectionUtils 或专规要求的封装覆盖,优先项目工具,避免同一业务混用多种风格。
  • 【推荐】(tc-fms)单次遍历合并逻辑:对同一集合,优先一次循环内完成多项相关处理(如过滤 + 分组键计算 + 累计),避免为图省事对同一集合多次遍历;若为此需用一层「仅做单一映射」的集合工具链、改为显式 for 以合并逻辑,可接受,以可读性与性能综合权衡为准;仍须遵守业务代码不直接使用 stream() 链的专规,复杂转换入口集中到 CollectionUtils 等(见「集合处理」【强制】tc-fms 条)。

(六)并发处理

  • 【强制】 单例及其中方法须线程安全。
  • 【强制】 线程、线程池命名有意义。
  • 【强制】 线程资源通过线程池提供,禁止随意 new Thread
  • 【强制】 线程池使用 ThreadPoolExecutor 显式构造,禁止 Executors 默认工厂(队列/线程数无界导致 OOM 风险)。
  • 【强制】 SimpleDateFormat 线程不安全;勿随意 static,若 static 须加锁或 ThreadLocal;JDK8 可用 LocalDateTimeDateTimeFormatter
  • 【强制】 同步调用评估锁开销:能无锁则无锁;能锁块不锁方法;能对象锁不类锁;锁内不调 RPC。
  • 【强制】 多资源加锁顺序一致,避免死锁。
  • 【强制】 并发更新同一条记录须防丢失更新(应用锁/缓存锁/DB 乐观锁 version 等)。
  • 【强制】 Timer 多任务时一处未捕获异常会导致其它任务停,宜用 ScheduledExecutorService
  • 【推荐】 CountDownLatch 异步转同步时,子线程 finally 或确保 countDown,并 catch 异常。
  • 【推荐】 避免多线程共享 Random 实例竞争 seed;JDK7+ 可用 ThreadLocalRandom
  • 【推荐】 双重检查锁单例须将目标字段声明为 volatile(JDK5+)。
  • 【参考】 多写场景 volatile 不够;count++AtomicInteger;JDK8 可用 LongAdder
  • 【参考】 HashMap 并发 resize 风险;高并发考虑替代结构或同步。
  • 【参考】 ThreadLocal 无法解决共享对象更新问题;实例建议 static

(七)控制语句

  • 【强制】 switch:每 casebreak/return 或注释说明继续执行;必须 default(可空)放最后。
  • 【强制】 if/else/for/while/do 必须使用大括号,禁止单行省略。
  • 【强制】 高并发场景避免用「等于某值」作为唯一中断条件,防止击穿,宜用区间判断。
  • 【推荐】 异常分支少用冗长 if-else,可用早返回;若必须 if-else if-else勿超过 3 层;可用卫语句、策略模式、状态模式。
  • 【推荐】 避免 if/else 分支体量严重失衡(一侧大段逻辑、另一侧仅少量语句,俗称「胖分支 / 瘦分支」),以免阅读时重心偏移、后续改动易漏改薄分支。优化思路:卫语句提前返回把简单条件或异常路径放在前;提前初始化默认值或中性状态,主流程只写与条件相关的增量逻辑;必要时将大块分支提取为私有方法,使 if/else 两侧在抽象层次上大致对称。
  • 【推荐】 条件判断中除简单 get/is 外,复杂逻辑先赋给有意义的 boolean 变量再判断。
  • 【推荐】 循环内避免重复创建对象、重复获取连接、不必要 try-catch。
  • 【推荐】 少用取反运算符,优先正向比较。
  • 【推荐】 批量接口做入参保护(数量上限等)。
  • 【参考】 参数校验:低频、高耗时、高稳定、对外接口、敏感入口须校验;极高频内层、已保证入参的 private 可省略并文档说明。
  • 【推荐】(tc-fms)卫语句与提前返回卫语句提前返回小范围前置条件检查(「钩子」),避免单个 iftry 包裹大段主干代码导致缩进过深、难测难改。
  • 【推荐】(tc-fms)条件判断顺序本地可完成的校验(非空、格式、正则、日期合法性等),访问数据库、缓存、远程接口避免廉价校验失败仍白耗一次 I/O。
  • 【推荐】(tc-fms)同线程内结果复用:在同一请求/线程内,对查询结果分支选择结果昂贵计算结果,赋给局部变量或轻量上下文复用避免重复查询与重复计算。
  • 【推荐】(tc-fms)代码局部性:变量声明首次使用尽量邻近避免先声明再穿插大量无关逻辑后使用;避免数据已查询却长期不使用、隔很远才使用,增加阅读负担与出错面。
  • 【推荐】(tc-fms)Web 请求内数据传递:在单次 HTTP 请求链路内传递请求级辅助数据,优先使用 HttpServletRequest#setAttribute(及等价请求作用域机制),慎用线程局部变量替代可放入请求作用域的数据,降低错配与泄漏风险。

(八)注释规约

  • 【强制】 类、类属性、类方法的注释用 Javadoc /** */,不用 // 代替类/方法说明。
  • 【强制】 抽象方法(含接口方法)须有 Javadoc:功能、参数、返回值、异常、调用注意。
  • 【强制】 类须有创建者与创建日期(团队统一格式即可)。
  • 【强制】 方法内单行注释写在被注释语句上方;多行用 /* */ 并对齐。
  • 【强制】 枚举项每项有注释。
  • 【推荐】 能用中文说清的用中文;专有名词保留英文。
  • 【推荐】 改代码同步改注释(参数、返回值、异常、核心逻辑)。
  • 【参考】 谨慎注释掉代码:说明原因或删除;TODO/FIXME 标注人、时间、预计处理时间,定期清理。

(九)其它

  • 【强制】 正则使用预编译:Pattern 定义为 static final,勿在方法内反复 compile
  • 【强制】 Velocity 访问 POJO 属性名规范;booleanBoolean 包装调用注意。
  • 【强制】 后台输出到页面的变量使用 $!{var} 形式,避免 null 原样输出。
  • 【强制】 Math.random()double 且含 0、不含 1;注意除零;整数随机用 Random#nextInt 等。
  • 【强制】 当前毫秒用 System.currentTimeMillis();纳秒统计用 System.nanoTime();JDK8 统计场景可用 Instant
  • 【推荐】 视图模板不写复杂逻辑。
  • 【推荐】 数据结构构造指定大小,避免无限增长。
  • 【推荐】 及时清理无用代码与配置;临时注释用团队约定(如 ///)说明理由。
  • 【推荐】(tc-fms)死代码与噪声:经确认不再引用的类、方法、代码块及无保留价值的注释及时删除,避免干扰阅读与检索。

(十)循环与性能(tc-fms)

  • 【强制】(tc-fms)循环体内禁止高开销 I/Ofor/while/do-while/foreach 的循环体中禁止执行数据库查询远程 RPC/HTTP 及其他高开销 I/O;应在循环外批量查询建映射聚合,循环内仅做内存侧处理与组装。
  • 【推荐】(tc-fms)尽早结束循环:在已命中目标满足提前结束条件时,使用 breakcontinue,或带标签跳出嵌套循环,避免无意义遍历剩余元素。
  • 【强制】(tc-fms)递归须可终止:递归须有明确的基准情形规模递减(或等价保证),所有分支须通向出口return 或改为迭代),禁止遗漏终止路径导致栈溢出或进程不可用。
  • 【推荐】(tc-fms)缺省与空容器优先返回 Collections.emptyList()new ArrayList<>()new HashMap<>()空容器代替裸露的 nullMap 等使用 getOrDefault 等,减少 NPE 与冗长判空(与对外契约中「是否允许 null」保持一致)。
  • 【推荐】(tc-fms)编译警告重视编译器与静态检查警告目标零警告(或团队白名单);新增代码不得滥用 @SuppressWarnings 掩盖应修复的问题。

二、异常日志

(一)异常处理

  • 【强制】 可通过预检查避免的 RuntimeException(如 NPE、越界)不要用 catch 处理;无法预检的例外(如 NumberFormatException)才可 catch。
  • 【强制】 异常不作流程控制、条件分支。
  • 【强制】 区分稳定代码与非稳定代码;catch 粒度适当,勿一大段 try-catch。
  • 【强制】 catch 后要处理或向上抛;最外层业务须转化为用户可理解信息。
  • 【强制】 事务中 catch 若需回滚须手动回滚。
  • 【强制】 finally 关闭资源;JDK7+ 用 try-with-resources。
  • 【强制】 finally 中禁止 return
  • 【强制】 捕获类型与抛出类型匹配或为父类。
  • 【推荐】 可返回 null 时须注释说明场景;调用方防 NPE(返回类型、DB、集合元素、RPC、Session、级联调用等);可用 Optional(JDK8)。
  • 【推荐】 区分 checked/unchecked;抛有业务含义的自定义异常,避免裸 RuntimeException、一般避免直接抛 Exception/Throwable
  • 【参考】 对外 HTTP/API 用错误码;内部可抛异常;跨应用 RPC 可用 Result(isSuccess、错误码、简短信息)。
  • 【参考】 DRY:多处相同校验抽取私有方法。
  • 【推荐】(tc-fms)异常与对外文案:异常信息、错误码说明、接口返回中的用户可见/运维可读描述须简明、准确、专业避免口语化、戏谑或歧义表述,确保可定位问题不误导调用方。

(二)日志规约

  • 【强制】 使用 SLF4J API,不直接依赖 Log4j/Logback 实现类。
  • 【强制】 日志文件至少保留 15 天。
  • 【强制】 扩展日志命名:appName_logType_logName.log
  • 【强制】 trace/debug/info 须条件输出或占位符,避免无谓拼接与 toString
  • 【强制】 避免重复打印;log4j 等配置对重复 logger 设 additivity=false
  • 【强制】 异常日志包含现场信息与堆栈:logger.error("context {}", obj, e)
  • 【推荐】 生产慎打 debug;info 有选择;warn 观察日志注意磁盘。
  • 【推荐】 用户参数错误可用 warn,非必要不打 error 刷屏。
  • 【推荐】 日志描述优先英文;说不清可用中文;国际化/海外部署考虑全英文。

三、单元测试

  • 【强制】 AIR:Automatic、Independent、Repeatable。
  • 【强制】 全自动、非交互;用 assert,禁止 System.out 人肉验。
  • 【强制】 用例互不依赖、无顺序依赖。
  • 【强制】 可重复执行,不依赖外部环境(网络等);依赖通过注入替换为 Mock/内存实现。
  • 【强制】 粒度小到方法级为主;核心业务增量代码保证单测通过。
  • 【强制】 测试代码仅在 src/test/java
  • 【推荐】 语句覆盖率目标约 70%;核心模块语句与分支覆盖率更高。
  • 【推荐】 BCDE:边界、正确输入、结合设计、错误输入。
  • 【推荐】 DB 相关不假设数据已存在;用程序准备数据;可自动回滚或测试数据前缀。
  • 【推荐】 不可测代码先重构;提测前完成单测,而非上线后补。
  • 【参考】 避免构造过重、过多全局静态、过多外部依赖、过多条件(需策略/状态等重构)。

四、安全规约

  • 【强制】 个人页面与功能须权限校验(含水平越权)。
  • 【强制】 敏感数据展示须脱敏。
  • 【强制】 SQL 参数绑定或元数据限定,禁止拼接 SQL。
  • 【强制】 所有入参有效性校验(page size、order by、重定向、注入、反序列化、ReDoS 等)。
  • 【强制】 禁止向页面输出未过滤/未转义的用户数据。
  • 【强制】 表单与 AJAX 提交 CSRF 校验。
  • 【强制】 短信、邮件、下单、支付等平台资源须防重放(次数、频率、验证码等)。
  • 【推荐】 UGC 场景防刷、违禁词等风控。

五、MySQL 数据库

(一)建表规约

  • 【强制】 是/否概念:is_xxx,类型 unsigned tinyint(1/0);非负字段 unsigned。
  • 【强制】 POJO 布尔不加 is 前缀时,与 is_xxx 字段在 ORM 中映射。
  • 【强制】 表名、字段名小写字母或数字;禁止数字开头;禁止两下划线间仅数字。
  • 【强制】 表名不用复数名词。
  • 【强制】 禁用保留字(descrangematch 等)。
  • 【强制】 主键索引 pk_字段名;唯一 uk_字段名;普通 idx_字段名
  • 【强制】 小数用 decimal,不用 float/double
  • 【强制】 定长用 charvarchar 长度合理,超长文本用 text 并独立表关联。
  • 【强制】 表必备:idgmt_creategmt_modified(类型与自增策略按实际规范;本项目若用 create_time/update_time 则遵循项目表结构)。
  • 【推荐】 表名体现业务与作用;库名与应用名一致;改字段含义须更新注释;可冗余字段须考虑一致性与变更频率。
  • 【推荐】 单表行数/容量达一定规模再考虑分库分表,忌过早拆分。
  • 【参考】 按业务选合适长度与无符号类型。

(二)索引规约

  • 【强制】 业务唯一字段(含组合)建唯一索引。
  • 【强制】(tc-fms)登录名/账号类字段:须在数据库层保证业务唯一(唯一索引或等价约束);若用户表采用逻辑删除,须对账号字段做置空、加前后缀打乱等处理,避免与唯一约束冲突及被重复占用。
  • 【强制】 超过三个表禁止 join;join 字段类型一致且被关联字段有索引。
  • 【强制】 varchar 索引须指定索引长度(按区分度)。
  • 【强制】 搜索禁止左模糊/全模糊依赖普通索引,应搜索引擎等方案。
  • 【推荐】 order by 与组合索引顺序配合,减少 file sort。
  • 【推荐】 覆盖索引减少回表;深分页用延迟关联或子查询优化。
  • 【推荐】 explain 目标至少 range,追求 ref/const;组合索引高区分度在左;注意隐式类型转换导致索引失效。
  • 【参考】 避免索引滥用或过度抵制唯一索引。

(三)SQL 语句

  • 【强制】 统计行数用 count(*),不用 count(列名)count(常量) 替代标准语义(注意与 NULL 行为差异)。
  • 【强制】 理解 count(distinct col) 与多列时 NULL 行为。
  • 【强制】 全 NULL 列时 sum 为 NULL,注意 NPE,可用 IF(ISNULL(SUM(g)),0,SUM(g)) 等。
  • 【强制】 NULL 比较用 ISNULL() 等,勿直接 = NULL
  • 【强制】 分页若 count 为 0 直接返回,不再执行后续分页 SQL。
  • 【强制】 不使用外键与级联,应用层解决一致性。
  • 【强制】 禁止使用存储过程。
  • 【强制】 数据订正前先 select 确认。
  • 【推荐】 in 控制集合大小(如千级内评估)。
  • 【强制】(tc-fms)动态 IN 与空集合:拼接 IN (...)必须判断入参集合非空;空集合时不得生成 IN () 非法 SQL,应改写查询分支(如永假条件、跳过该条件、或短路不查),语义须与业务一致。
  • 【推荐】(tc-fms)大字段与富文本:列表、检索、导出等场景尽量避免 SELECT 大文本TEXT/LONGTEXT、富文本、大 JSON 等);在详情、编辑、下载等必要场景按需加载,减轻数据库与网络传输压力。
  • 【参考】 字符集 utf-8/utf8mb4;LENGTH vs CHARACTER_LENGTH;慎用 TRUNCATE

(四)ORM 映射

  • 【强制】 查询不用 SELECT *,列名写清。
  • 【推荐】(tc-fms)按需列:除禁止 SELECT * 外,仅查询当前用例所需列;DTO/VO 映射与 ResultMap 亦避免无谓映射大字段(与「大字段」条款配合)。
  • 【强制】 POJO 布尔与 is_xxx 字段在 resultMap/注解中映射。
  • 【强制】 返回类型用明确类,不用模糊 resultClass 凑合;表与 DO 一一对应。
  • 【强制】 MyBatis 参数用 #{},禁止 ${} 拼接(防注入)。
  • 【强制】 禁止大分页式「全量查出再 subList」的 API 用法。
  • 【强制】 禁止 HashMap/Hashtable 作为查询结果类型滥用。
  • 【强制】 更新记录须同步更新修改时间字段(与项目字段名一致)。
  • 【推荐】 避免大而全 update,只更新变更字段。
  • 【强制】(tc-fms)批量与 foreach 长度:使用 MyBatis 批量插入/更新/foreach 拼接 IN 等时,根据驱动与包大小限制评估入参集合长度;过大分批执行(如按团队约定的每批条数拆分),避免单条 SQL 过长、参数包过大或超出数据库限制。
  • 【参考】 @Transactional 慎用,考虑缓存/消息等一致性与回滚。

六、工程结构

(一)应用分层

  • 【推荐】 开放接口层、终端显示层、Web 层、Service 层、Manager 层、DAO 层、外部系统依赖关系清晰,上层可依赖下层,忌循环依赖。
  • 【参考】 分层异常:DAO 可包装 DAOException;Service 记磁盘日志带参数;Web 顶层勿继续抛未处理异常到用户;开放接口转错误码。
  • 【参考】 领域模型:DODTOBOAOVOQuery;超过 2 个参数封装查询对象,禁止 Map 传递。

(二)二方库依赖

  • 【强制】 GAV:GroupIdcom.{公司/BU}.业务线ArtifactId 产品线-模块名;版本语义化。
  • 【强制】 版本号:主.次.修订;起始 1.0.0;正式版不覆盖升级。
  • 【强制】 线上不依赖 SNAPSHOT(安全包等例外说明)。
  • 【强制】 二方库升级若传递依赖变化须评估,可用 dependency:tree 比对。
  • 【强制】 二方库接口返回值不用枚举或含枚举的 POJO(客户端兼容)。
  • 【强制】 同批依赖统一版本变量,禁止同 GroupId+ArtifactId 不同 Version 出现在子模块。
  • 【推荐】 依赖声明与版本管理分块;二方库少配置项。

(三)服务器(参考)

  • 【推荐】 高并发下调小 time_wait;调大 fd;OOM 时 -XX:+HeapDumpOnOutOfMemoryError;生产 Xms=Xmx;内外部重定向方式区分。

七、设计规约

  • 【强制】 存储方案与核心数据结构评审通过并文档化;上线后 double check;变更须评审。
  • 【强制】 多类用户且用例 >5:用用例图。
  • 【强制】 业务状态 >3:用状态图并标明触发条件。
  • 【强制】 调用链路对象 >3:用时序图并标明输入输出。
  • 【强制】 模型类 >5 且依赖复杂:用类图。
  • 【强制】 多对象协作且流程复杂:用活动图。
  • 【推荐】 评估异常流程与边界;单一职责;优先组合优于继承(继承须符合里氏替换);依赖倒置;对扩展开放、对修改关闭;共性抽取避免重复。
  • 【推荐】 敏捷仍须在关键点有设计与文档。
  • 【推荐】(tc-fms)实现功能时,不宜止步于「当前调用点能跑通」;宜审视调用方是否因重复传参、重复判空、重复拼装而臃肿。若通过对合适层次适度扩展即可收敛多处逻辑——例如为同一语义提供重载、在通用工具类增补可复用的静态方法、在基础设施提供批量/聚合能力以替代循环单次调用——应优先采用,使调用方更短、更一致。扩展须落在职责与分层匹配的模块,避免在业务类中堆积仅服务单次场景的变通写法;新增或重载的公开方法须符合空安全、命名与模块边界,并评估对现有调用方的影响。
  • 【参考】 设计为理清需求与维护服务;识别变化点并隔离;架构明确边界、模块关系、演化原则、非功能需求(安全、可用、扩展等)。
  • 【推荐】(tc-fms)避免过度设计「为模式而模式」、不合理的方法抽取、职责涣散的工具类、无必要的深层抽象与层层包装;在可维护性复杂度之间取平衡,优先简单清晰、可演进的结构。
  • 【参考】(tc-fms)统计与聚合位置适度在应用层做统计、聚合、规则裁剪(易单测、易扩展、行数可控),可辅以缓存或结果表;一味将复杂统计塞进单条 SQL;结合数据量与团队能力在 SQL 与代码之间取舍。

附:与 tc-fms 项目对齐(摘要)

  • 分层调用链以项目 AGENTS.md 为准;Entity 字段、审计列名可能与手册 gmt_* 示例不同,以本项目表结构与 BaseEntity 为准
  • Map 局部变量/字段命名建议 {键语义}K{值语义}Pair(见「命名风格」【推荐】)。
  • Bean 转换使用项目 BeanUtils;API 统一 ResponseDTO/PageDTO
  • 分页:IPage<实体>IPage<VO/DTO> 使用 com.tc.fms.common.utils.collection.CollectionUtils#convertPage(见上文「集合处理」【推荐】);禁止在无充分理由时手写 Page 拼装分页结果。
  • Java 仅使用 8 语法;手册中 JDK8+ 特性按项目允许范围使用。
  • 工具类静态方法优先 静态导入(见「代码格式」);泛型须写全、构造与可推断处用 diamond <>(见「OOP 规约」tc-fms 条)。
  • 集合/字符串判空与常用操作优先 Hutool CollUtil / ListUtil / StrUtil 等(见「集合处理」【推荐】),与 CollectionUtils 优先级关系见该条。
  • 抽取私有/辅助方法时优先传 DTO/实体等聚合对象,避免把同一对象的多个 getXxx() 拆成一长串参数(见「OOP 规约」【推荐】tc-fms 条)。
  • 循环与批量:见「循环与性能(tc-fms)」;动态 IN、大字段、MyBatis 分批见「MySQL」「ORM 映射」中 tc-fms 条;枚举优先与废弃 API 见「常量定义」「OOP 规约」。
  • Web 请求内数据优先 request 作用域;卫语句、条件顺序、同线程复用、代码局部性见「控制语句」tc-fms 条。

执行优先级:【强制】>【推荐】>【参考】;评审与 CI 以团队约定为准。用户指定 阿牛规范 / drin.rule 时,视为要求完整执行本规则文件。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐