Java开发规范

Java开发规范
一、编码
编码主要参考阿里规范,详情见附件

1.1 编码质量
1.1.1 指标
● 编译告警数,大部分程序员基本上忽略 warning,但是编译器出现了告警是一种不好的体现,意味着软件可能工作,但是存在不好的实践,而这种不确定性,会带来不确定的 bug 最终让人一头雾水。编译过程中的告警,尽量消除掉,编译告警的值推荐消除到 0。
● 平均函数代码行数,过大的函数会导致阅读困难,而且往往过大的函数职责不够单一,一般将一个方法代码行数控制到 30 - 50 行。
● 平均文件代码行,和平均函数代码行一样,过长的文件一样难以维护,一般一个文件10多个方法,因此文件的代码行数一般控制到 300 - 500 行。
● 冗余代码,有时候我们代码中可能存在未使用的方法、变量等代码,这让维护者一头雾水,通常需要清零。
● 总文件重复率,出现重复文件的次数。除了编写单元测试的情况下,业务代码不应该出现重复代码,推荐值为 0。
● 总代码重复度,代码的重复度检查,限于扫描工具的识别模式,需要有一定的容忍度,推荐值在 5% - 10%
● 平均函数圈复杂度,圈复杂度用来衡量一个模块判定结构的复杂程度。如果一个方法内部有大量的 if 语句嵌套,意味着这个方法的实现质量低下,且程序复杂度高不利于维护,推荐值小于 5%。
● 安全告警,如果配置了安全扫描工具,例如 Fortify,安全威胁应该被清零。
● 代码缺陷,如果配置了缺陷扫描工具,例如 Findbugs,需要清零。
1.1.2 检查项

检查项工具目标当前
代码风格检查checkstyle0
编译告警数checkstyle0
平均方法代码行数checkstyle30-50
平均文件代码行数checkstyle300-500
冗余代码checkstyle0
总文件重复率checkstyle0
总代码重复率checkstyle5%-10%
平均方法圈复杂度checkstyle<=5%
安全高级sonarqube0
代码缺陷sonarqube findbugs0

1.1.3 使用
mvn checkstyle:checkstyle

1.1.4 checkstyle检查规则
如有补充调整, 请修改项目中的checkstyle.xml文件
请严格按照 https://checkstyle.sourceforge.io/checks.html 官方 module name 及 parent位置添加规则模块, 否则xml文件加载会报错

类别检查项规则
注释检查
命名检查(AbstractClassName)抽象类名称^Abstract.+$, 抽象类名必须由Abstract 开头
(ConstantName)全局常量名称(static final)^ [A-Z][A-Z0-9](_[A-Z0-9]+)$ , 全部大写加下划线
(LocalFinalVariableName)局部final变量名称^ [A-Z][A-Z0-9](_[A-Z0-9]+)$ , 全部大写加下划线
(LocalVariableName)局部变量名称^ [a-z][a-zA-Z0-9]*$, 驼峰命名
(MemberName)成员变量(非静态字段)名称^ [a-z][a-zA-Z0-9]*$, 驼峰命名
(MethodName)方法名称^ [a-z][a-zA-Z0-9]*$, 驼峰命名
(PackageName)包名称^ [a-z]+(.[a-z][a-z0-9])$, 全部小写
(ParameterName)参数名称^ [a-z][a-zA-Z0-9]*$, 驼峰命名
(StaticVariableName)静态变量名称(用static修饰,但没用final修饰的字段)^ [a-z][a-zA-Z0-9]*$, 驼峰命名
(TypeName)类(接口)名称^ [A-Z][a-zA-Z0-9]*$, 驼峰命名, 首字母大写
导入检查(IllegalImport)非法包导入默认: 拒绝所有 sun.* 包
(RedundantImport)冗余导入当一个类被导入不止一次时。非静态导入的类来自java.lang 包,例如 importing java.lang.String。非静态导入的类与当前包来自同一个包。
(UnusedImports)未使用的导入和冗余导入校验类似, 主要处理导入类型与声明名称相同的情况
长度检查(FileLength)源码文件的长度一个文件所能容许的行数 最多500行
(LineLength)源码每行的长度一行最多200个字符, 排除注释行的限制
(AnonInnerLength)匿名内部类的长度匿名内部类最多20行
(MethodLength)方法的长度每个方法最多50行(包含空行)
(ParameterNumber)方法参数数量每个方法最多10个参数
空格检查(可有可无, IDEA标准格式化即可)(EmptyForInitializerPad)for循环初始化语句填充符for(int i = 0; i < 100; i++) 正确for(int i=0; i<100;i++) 错误
(EmptyForIteratorPad)for iterator语句是否使用空格IDEA标准格式化即可
(NoWhitespaceAfter)指定标记之后有没有空格, IDEA标准格式化即可
(NoWhitespaceBefore)指定标记之前有没有空格, IDEA标准格式化即可
(MethodParamPad)方法定义、构造器定义、方法调用、构造器调用的标识符和参数列表的左圆括号之间的填充符IDEA标准格式化即可
(ParenPad)圆括号的填充符策略IDEA标准格式化即可
(TypecastParenPad)类型转换的圆括号的填充符策略IDEA标准格式化即可
(WhitespaceAfter)指定标记之后是否紧跟了空格IDEA标准格式化即可
(WhitespaceAround)指定标记的周围是否有空格IDEA标准格式化即可
修饰符检查(ModifierOrder) 修饰符顺序正确的顺序应当如下:1. public 2. protected 3. private 4. abstract 5. static 6. final 7. transient 8. volatile 9. synchronized 10. native 11. strictfp
(RedundantModifier) 冗余的修饰符1. 接口和注解的定义;2. final类的方法的final修饰符;3. 被声明为static的内部接口声明
代码块检查 (括号位置检查可有可无, IDEA标准格式化即可)(AvoidNestedBlocks) 嵌套代码块找到嵌套代码块,也就是在代码中无节制使用的代码块
(EmptyBlock) 空代码块查找代码块中不包含内容的
(LeftCurly) 代码块的左花括号的放置位置左括号位置和名称定义在同一行, 不换行(IDEA标准格式化即可)
(NeedBraces)代码块周围是否有大括号检查do、else、if、for、while等关键字所控制的代码块 禁止: if (obj.isValid()) return true;
(RightCurly)代码块的右花括号的放置位置IDEA标准格式化即可
编码检查(CovariantEquals) 重载equals 方法重载equals方法时, 需要重写覆盖equals(Object o); 方法
(DefaultComesLast) switch case代码块中default的位置default应放在所有的case分支之后
(MissingSwitchDefault) switch 中 default语句switch case 中必须要有default语句
(EmptyStatement) 空语句禁止出现独立的 “;”
(EqualsHashCode) 重写equals 方法重写equals方法时, 需要重写 hashCode 方法
(FallThrough) switch case代码块中的跳出语句case 分支 必须存在 break、return、throw或continue语句
(HiddenField) 变量名冲突检查局部变量是否会遮蔽在相同类中定义的字段
(IllegalInstantiation) 不必要的实例化操作目前只针对 Boolean 和 Integer 检查是否存在不必要的实例化操作, 使用工厂更合适, 例: new Integer(int i); -> Integer.valueOf(int i);
(InnerAssignment) 子表达式赋值禁止子表达式中的赋值操作, 提高可读性, 例: String s = Integer.toString(i = 2)
(MagicNumber) 幻数禁止出现未定义成常量的数字, (排除0, 1, -1和注解上的数字)
(MultipleStringLiterals) 相同字符串控制当一个文件中出现3次以上相同的字符串时, 应定义为常量
(MultipleVariableDeclarations) 变量的声明禁止在同一行声明多个变量, 例: int lower, higher; int place = mid, number = high;
(NestedIfDepth) if else 嵌套层数禁止if else 嵌套超过3层, 超过请重构
(NestedTryDepth) try catch 嵌套层数禁止try catch 嵌套超过2层, 超过请重构
(ParameterAssignment) 方法参数赋值禁止对方法的参数进行重新赋值, 如需必要, 请重新定义变量, 修改变量值
(ReturnCount) 方法中return数量限制方法、构造方法、lambda表达式中return 个数, 最多10个
(SimplifyBooleanExpression) 复杂布尔表达式检查是否存在复杂布尔表达式, 例: if (b == true)、b
(SimplifyBooleanReturn) 复杂布尔返回检查是否存在复杂布尔返回, 例: if (valid()) return false; else return true; 改为: return !valid();
(StringLiteralEquality) 比较字符串相等比较两个字符串相等必须使用 equales 方法, 禁止使用 “==”
(TodoComment) TODO请及时更新补充TODO内容
(LambdaBodyLength) lambda 表达式长度提高可读性, lambda表达式长度不能超过10行, 超过请提取方法
(LambdaParameterName) lambda 参数^ [a-z][a-zA-Z0-9]*$, 驼峰命名
类设计检查(InterfaceIsType) 空接口禁止一个接口中只定义变量 或 是一个空接口
(ThrowsCount) throw 数量限定一个方法可抛出的异常数量最大为5个
度量检查(CyclomaticComplexity) 循环复杂度一个方法出现if、while、do、for、?:、catch、switch、case等语句,以及&&和
其他检查(Indentation) 代码缩进IDEA标准格式化即可
(UpperEll) long类型的常量定义小写的 “l” 和 数字 “1” 很相似, 应定义为 “L”

1.1.5 强制规范

  1. mybatis-plus sql 字段名不能直接使用字符串,使用 LamdaWrapper
  2. 返回数据格式统一用 Response,不可以直接返回 map、void、string、object
  3. 数据传输禁止使用map交互, 定义VO或者DTO
  4. dao层不能含有大量的业务处理逻辑, 放到领域层(domain)
  5. 不能直接在代码中拼接字符串sql, 如有必要 定义在xml中
  6. 异常尽量抛出交给全局异常处理, 如必须捕获处理, 需将完整堆栈信息打印出来, 不允许私吞
  7. 命名符合驼峰规则及尽量有意义, 不用 XXX_1, XXX_2, XXX_3 数字区分
  8. 接受统一用json协议,参数不能直接 getParamter 获取
  9. 尽量单表操作, 不使用 left join
  10. 统一分页规范, 使用公共 PageUtils, PO继承公共PageQry
  11. 方法开头不需要打印参数日志, 统一交给切面打印
  12. 入参校验统一使用JSR303
  13. 对象空校验阻断业务流程时统一使用AssertUtil工具类抛出异常
  14. 多状态多类型字段需强制使用Enum

二、日志
2.1 使用
● 统一使用 lombok @Slf4j 注解。
● 必须使用参数化信息的方式,不要进行字符串拼接,那样会产生很多String对象,占用空间,影响性能。

log.debug("Processing trade with id:[{}] and symbol : [{}] ", id, symbol);

三、异常 & 监控
3.1 异常 & 错误码
BizException
业务提示性的异常,比如:当前用户未登录,权限不足等。
不需要catch打印,直接抛出BizException,系统统一捕获并打印具体错误信息。

SystemException
影响到程序正常运行,需要开发处理的异常。
不需要catch打印,直接抛出SystemException,系统统一捕获并打印具体错误信息。
3.2 监控
对 controller做切面拦截,统一输出日志

3.2.1 告警规则
系统异常(SystemException)一定告警
3.2.2 监控指标
3.2.2.1 系统指标
接口请求量
活跃用户
高频接口
TPS
接口耗时
系统异常
3.2.2.2 业务指标

四、分层 & 分包
4.1 模块
scrm-api
作为被依赖服务,提供给其他服务的接口
scrm-common
公共模块,放置util等
scrm-web
核心服务
4.2 分层
参考:https://gitee.com/chyj77/ddd-cargo
interfaces(表现层)
查询数据:Qry(读)
命令:Cmd(写)
业务层之间的数据对象:VO(Value Object)
application (应用层)
标准参数:Specification
domain (领域层)
DDD 中的实体 DO(Domain Object)
infrastructure (基础设施层)
访问数据库的:DAO (Data Access Object数据访问对象)、Mapper
与数据库表结构对应:PO

4.3 DDD规范
4.3.1 基本分层引用链
情形一:业务简单
interfaces -> application -> infrastructure
情形二:业务复杂
interfaces -> application -> domain -> infrastructure
在这里插入图片描述

4.3.2 各层类文件规范
interfaces :controller
application: VO 、qry、cmd、service
调用规则:application调用domain/infrastructure 只允许传递DO/Specification/aggregate/context 后缀的类 不允许传递Qry/Cmd后缀的类
domain: domainService、context、aggregate、factory、event
调用规则:domain调用infrastructure 只允许传递DO/Specification 后缀的类或者单参数形式
infrastructure: PO、DO、Specification
调用规则:所有sql查询处理必须在dao层 不允许出现在其他层 查询出来的对像统一需要返回DO出去

具体调用细则 查看示例类 com.jb.scrm.interfaces.web.demo.DemoController

五、代码提交
必须经过 2次 code review,第一次主要检查编码规范,第二次主要检查业务逻辑。
六、单元测试
unit test 覆盖率大于 20%

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值