为什么要指定代码规范?
1.项目结构混乱
2.代码不规范,冗余,无从下手
导致 : 功能维护 的难度加大
>> 浪费时间去阅读源码
>> 烂代码里面继续写烂代码
>> 维护起来越来越困难
从技术上的角度来讲,你们认为什么样的代码才算好代码?
看不懂的代码才是好代码?
经过设计模式层层封装的代码才是好代码?
简洁明了,通俗一同,注释齐全 ==> 好代码 !
在注重功能,技术深度和广度的同时, 我们要懂原理,懂技术, 但是更重要的是写的一手好代码.
talk is cheap,show me your code !
代码编写 =(根据)=>规范=(养成)=> 代码风格 =(学会)=> 重构 =(培养)=> 代码设计 =(理解)=> 设计模式
代码规范的第一步,就是要培养代码风格
下面我们就从温州项目,一步步了解代码规范
1.架构
1.1技术
本项目是JavaWeb项目,使用了如下技术
- 流行的SSM框架;
- log4j2+slf4j+disruptor 作为异步日志组件
- druid 连接池
- fastjson和jackson json 工具
- AOP+aspect 控制事务和自定义注解
- swagger 文档工具
- httpclient 网络组件
- sigar + JMX 系统监控工具
- apace commons 系列开发工具
- Juint 单元测试
1.2 系统结构
系统结构尽量保持层次分明,结构简单.用包命名的方式区分业务系统代码和通用代码,如下图所示
- commons: 存放通用代码,比如各种工具类,常量类,日志组件等.commons下的代码主要服务于业务代码
- console: 主要针对web服务,提供访问接口,如登录注册,权限系统等,,但是独立cell的存在,有自己的一套访问数据库和业务逻辑.但是同样基于SSM架构.
- cell: 提供传统分层中的Service层和Mapper层.保持最小的基础逻辑单元,即单表的增删改查,分页查询和列表查询. 根据业务要求,也可以提供联表的查询服务. 联表查询时sql写在主表标注的位置下(如下图所示).我们建议,在联表查询中,尽量少的使用外联. 此外,在service中,我们不建议一个方法有更新或新增多张表的行为.尽量保持类的单一职责.如果需要多表操作,请在VS层完成.
- s001: 业务代码.负责提供对外访问业务接口(Controller),业务逻辑(VS)以及值对象(VO).其中以Controller为单位作为服务调用的功能接口.VS注入多个Service提供复杂的业务逻辑,在业务包下,我们指定如下规范:
- 以系统为单位,S开头加系统编号的形式做顶级业务包命名方式并作为系统编号,如S001;
- 以系统中的模块为单位,M开头加模块编号作为系统包下的模块包命名并作为模块编号,如M001;
- 以模块中的功能为单位,F开头加功能编号作为为模块中的具体功能命名作为功能编号,如F001Controller.以系统编号+模块编号+方法编号,如 /S001/M001/F001;URL前缀为
- save*
- update*
- query*
- view*
- delete*
- 以功能编号命名的VS层,与相同编号的Controller是一对一的关系,只服务此Controller.方法命名方式与URL前缀一致,用来控制事务.
2.开发规范
2.1 命名规范
- 英文命名尽量使用驼峰形式,拼音命名尽量通俗易懂,命名的方法或者属性尽量有意义,并容易理解
- 反例: int i = updateXXX(TSignInfo record);
- 正例: int signCount = updateTSignInfo (TSignInfo record);
- 系统编号, 模块编号,功能编号有项目经理提前指定并统一管理
- URL为系统编号+模块编号+功能编号+save*/update*/query*/view*/delete*
- VS层的方法命名,凡是对数据库操作的必须以save*/update*/delete*为前缀,方便事务控制
2.2 开发规范
- 类和方法必须写注释作为描述说明,接口方法上写明调用页面 . 静态常量要有业务场景或使用说明
- controller层必须进行数据校验
- 基本数据类型设置默认值. 如 pageSize = 10
- String类型的参数要做判空处理. (推荐使用 apache.commons.lang3.StringUtils)
- json类型的数据做json格式校验
- controller层数据返回必须按照规范
- 操作数据 使用 ResultModel ,异常使用 ResultModel 返回对应状态实体对象
- mini ui的分页查询 使用MiniList或者规定格式的数据作为返回值 ,异常时返回 {total:0,data:null} 字符串或者MiniList.emptyList();
- 字典表返回List,异常是返回 [] 字符串
- controller层必须进行异常时的数据返回处理
- controller层的每个接口方法必须使用try-catch捕获异常
- controller层每个接口方法必须做日志记录.
- VS层在进行数据库操作时,必须对操作返回的数值验证,不正常的返回值进行异常处理 如 update(T t) = 0
- service,dao必须继承 BaseService, BaseMapper接口,实现规范.生成的基础逻辑代码不可修改.有问题联系项目经理.查询代码可自己实现
- 代码中避免使用魔鬼数字,状态字段等尽量使用有意义的常量,并且使用常量类统一维护 反例 : obj.setStatus("1");
- 页面上的 操作请求 必须对返回值状态 进行判断 并进行相应的操作 ( 无论是成功还是失败);
- 精确计算时,必须使用BigDecimal. 避免使用float和double. 浮点运算必须使用BigDecimal或整型运算,如
- 0.5 * 0.01 >> 50*1