Java工程代码开发规范总结
做了这么多年开发,对于开发规范方面结合了多方资料,自行总结一些规则,便于参考。
本文档还在不断的补充和完善中,后续持续更新。
命名规范
工程命名
使用项目英文命名或使用拼音,可以使用缩写。工程名称为小写,不使用驼峰式。
正例:智能仓储管理系统InStock,工程名为instock。供应链产品平台Supply Chain ONE,工程名为sco
反例:InStock,SupplyChainONE
命名空间(package)命名
|--com
|--公司英文或拼音(可以缩写)
|--项目名称英文或拼音
|--一级模块名称英文(不要使用拼音,避免语义混淆,如:学校拼音(xx)与选修拼音(xx)完全相同)
|--二级模块名称英文(如果没有可以不设置该层级目录)
|--controller # 控制器层
|--service # service接口层
| |--impl # service接口实现类
| |--xxxx # 模块内服务层其他特殊代码分包(如模块内子业务)
|--dao # 数据访问层接口类
|--util # 本模块的工具类(如果没有可以不设置该层级目录)
|--yyyy # 模块内非服务层其他代码分包(如setting/exception/)
|--model
|--entity # entity 数据库实体对象
|--po # parameter object 参数数据携带对象
|--vo # view object 视图数据携带对象
|--dto # data transfer object 数据转换对象
|--annotation # 自定义注解类
|--enums # 枚举类(enum是关键字,不能直接作为报名,故为复数形式)
|--constant # 常量类
正例:com.inossem.instock
反例:com.inossem.controller(缺少产品/项目名)
文件命名
控制器:XxxController.java
Service接口:I(大写字母i) + Xxx + Service后缀,例如:IReceiptService.java(特殊的,对于从OOP设计角度出发的行为约束型接口,可以不加Service后缀,但仍需要有大写字母i做为前缀)
Service抽象类:Xxx + Service后缀,例如:UserService.java
Service实现类:XxxServiceImpl.java
Service辅助类:用于提取有业务共性的业务组件方法,命名为XxxServiceComponent.java
FeginClient:XxxFeignApi.java
工具类:UtilXxx.java(为了检索方便,将Util作为工具类统一前缀)
POJO类:XxxVO.java、XxxPO.java、XxxDTO.java。(entity不需要添加后缀,直接使用实体名,例如:User、Factory等)
枚举类:EnumXxx.java
常量类:统一使用一个常量类时可以命名为Const.java,有多个常量类时命名为ConstXxx.java,ConstYyy.java
异常类:公共异常,使用项目名缩写作为前缀 + 实际异常名 + Exception后缀,例如ScoException.java、InsException.java。其他具体异常,以Exception后缀结尾,异常名称应力求通过名称可以准确表达含义。例如:UserAuthorizationException.java
Java Configuration类(spring bean configuration):XxxConfig.java(例如:RedisConfig.java、QuartzConfig.java、ActiveMQConfig.java等)
处理类、过滤器、拦截器类、监听器:XxxHandler.java、XxxFilter.java、XxxInterceptor.java、XxxListener.java
变量&常量命名
变量
Java端的变量命名使用驼峰式命名法
力求表义完整,通过变量命名尽可能表示出此变量的用途或作用域
基本数据类型变量
对于布尔值变量命名,使用is+Done(过去分词)/is+Noun(名词)
举例:
是否已完成boolean isCompleted = false;(true表示已完成)
是否是草稿boolean isDraft = false;(true表示是草稿)
集合类型变量
采用集合内元素的类型+对应集合类型的规则。不要使用ids,users等名词复数命名(避免英文中不可数名词及名词复数拼写特例导致的单复数混乱,同时减少开发人员英语水平不同导致的命名差异)
List变量命名,举例:userList、userIdList(或idList)、inboundReceiptRidList(或ridList)
Set变量命名,举例:userSet
Map变量命名
领域模型及POJO对象变量
待补充
临时变量,中转参数
待补充
常量
常量名全部大写,连字符使用下划线。使用static + final修饰
力求表义完整,通过常量名尽可能表示出此常量的用途或作用域
正例:public static final int MAX_USER_ACCESS_LIMIT = 5; //明确作用和用途
反例:public int LIMIT = 20; //缺少修饰关键字,且表意不明确,难以分清是访问限制还是其他的什么限制
方法命名
新增
单条记录新增
insertXxx(Dao层)/addXxx(Controller&Service层),Xxx为名词单数形式
举例:insertReceipt 新增单据(Dao/Mapper层),addReceipt新增单据(controller/Service层)
批量新增
multiInsertXxx(Dao层)/multiAddXxx(Controller&Service层),Xxx为名词单数形式
举例:multiInsertReceipt 批量修改单据。
带有复杂筛选条件的新增
insertXxxByYyy(Dao层),service层命名不做限制
修改
单条记录修改
updateXxx(只做更新),Xxx为名词单数形式,条件参数使用对应领域模型传入。
saveXxx(Dao层/Service层相同)(保存或更新,记录存在则更新,记录不存在新增),Xxx为名词单数形式,条件参数使用对应领域模型传入。
批量删除
mutilUpdateXxx(只做更新),Xxx为名词单数形式。
multiSaveXxx(保存或更新,记录存在则更新,记录不存在新增),Xxx为名词单数形式。
删除
单条记录删除
deleteXxx,Xxx为名词单数形式,条件参数使用对应领域模型传入。
批量删除
multiDeleteXxx
查询
单条记录查询
selectXxxByYyy(Dao层)getXxxByYyy(controller&Service层),Xxx为名词单数形式,一般为要查找的领域模型,Yyy为查询条件,一般为Xxx的某个字段,多个条件时可以使用AndZzz表示。
举例:
(Dao层)selectUserById、selectReceiptByCode、selectBatchInfoByBatchCodeAndFtyCode
(Controller&Service层)getUserById、getReceiptByCode、getBatchInfoByBatchCodeAndFtyCode
列表记录查询
单组条件的列表查询
listXxxByYyy、listXxxByYyyAndZzz(举例:listUserByName、listUserByTitleAndLevel)
注意:这里前缀的list取的是动词含义列出,而不是列表。因此对于查询结果为Set或其他集合结构的方法,也都使用list前缀。用于区分单条记录查询和多条记录查询。
特殊的,当唯一条件的字段数量在两个及以上,且我们已经针对模型的唯一条件进行了封装时(例如:批次信息的唯一条件是批次编码+物料编码+工厂编码+特殊库存标识+特殊库存代码,这5个字段已经被封装成了一个单独的类),可以使用listXxxByUniqueKey 或listXxxByPrimaryKey 来代替。(注意:primaryKey的使用条件更为严格,要求对应字段必须是主键才能使用,如主键是id,唯一键是code+rid,则以code+rid为条件时不能使用PrimaryKey后缀,应使用UniqueKey后缀。)
多组条件的列表查询
输入条件是列表或集合时
listXxxByMultiYyy(举例:listUserByMultiName(根据用户名列表查询用户))
对于主键和唯一键的封装字段替换与单组条件规则相同
分页记录查询
listXxxOnPaging
数据库相关命名规范
数据库相关命名,使用蛇形命名法,单词之间以单下划线分割,统一使用小写
表名
为了使数据库表在数量较多时仍然有序且便于查找,数据库表命名时,按照功能和作用进行分类,并加以不同前缀。
业务表
以biz开头,例如:biz_receipt、biz_wave_inbound
命名时,注意在不影响语义的情况下,适当调整单词位置,使相同或相似业务的表能够在按照字母序排序时,显示在一起。便于开发期间快速查找。
正例:
入库单据表&出库单据表起名为
biz_receipt_input
biz_receipt_output
反例:
biz_input_receipt
biz_output_receipt
注意:在大多数情况下,模型名、库表名、JavaBean名可能会是一样的。但库表的名字不应当强制性的要求与业务建模时的模型名称以及JavaBean的名称一致。ORM始终是一种映射,不代表完全一致。(此处对于直接使用MyBatis等框架做逆向工程时有一定冲突,使用时需要注意识别)
待补充
系统配置数据表
待补充
视图名
以v或view开头(项目中统一选择其中一种前缀)
举例:v_receipt 单据视图
函数名
以func开头
举例:func_next_biz_code(计算下一个业务编码函数)
触发器名
插入触发器以insert开头+触发时机(before/after)+业务名称
更新触发器以update开头+触发时机(before/after)+业务名称
保存触发器(插入or更新)以save开头+触发时机(before/after)+业务名称
删除触发器以delete开头+触发时机(before/after)+业务名称
举例:update_after_stock(库存更新后置触发器)
注意:在java编程中尽量不使用触发器处理业务逻辑,而是将逻辑写在Java的service层代码中。
存储过程名
以proc开头
举例:proc_stock_update
文件位置规范
Maven工程
资源文件
放置在resources目录下
|--src
|--main
|--resources
|--mapper # 存放mybatis mapper
| |--subdir # 业务子目录
| |--businessMapper.xml # 具体mapper文件
|--application.yml # SpringBoot配置文件
|--log4j2.xml # 日志配置文件
代码文件
普通Java类
放置在java目录下,目录名称全部小写,出现多个词时,优先考虑是否是分包不合理(例如可以再细分成一个子目录等),实在需要多个词时,将多个词拼接在一起,不使用驼峰。
例如:
正例:com.inossem.instock.common.datasource
反例:com.inossem.instock.common.dataSource(不应使用驼峰)
|--src
|--main
|--java
|--com.inossem.instock
|--inbound
|--instock
|--outbound
|--gateway
|--...
SpringBoot启动类(Application.java)
使用工程名或模块或微服务名 + Application后缀命名
例如:InStockApplication.java、ScoApplication.java(以工程名为前缀)、WmsApplication.java(以模块名为前缀)、GatewayApplication.java(以服务名为前缀)