二、冲刺任务与计划
时间\任务 |
前端 |
后端 |
4.26 |
项目部署、熟悉开发环境 |
项目部署、熟悉开发环境 |
4.28 |
登录注册页面 |
登录注册、用户信息接口 |
4.30 |
前台获取表单列表及内容;后台主要功能布局 |
表单相关接口实现 |
5.1 |
前台表单提交功能;后台部分表格实现 |
人员管理接口 |
5.2 |
前台小组页面;后台表格实现 |
班级、团队接口 |
5.3 |
统计页面 |
分数核算功能 |
5.4 |
功能完善 |
信息统计接口 |
5.5-5.7 |
前后端连接测试与完善 |
前后端连接测试与完善 |
二、代码规范
1. 命名规范
1.1 总体命名规则
1. 名字含义要明确,做到见名知义,如: User,Customer
2. 尽量少用缩写,必须确保能让人看懂含义。
1.2 变量名
1. 小驼峰式命名,变量名首字母必须为小写字母,不使用 “_” 作为变量名(包括成员变量)开头
2. 尽量使用英文作为变量名, 若使用汉语拼音,必须注释清楚
3. 正确:userName 错误:UserName,_UserName,username ```
1.3 常量名
1. 常量名必须全部为大写
2. 各单词必须以下划线分开,以便区分
3. 对于枚举类常量,如:状态,尽量使用Enums定义 如
public enum ApplStatus implements ResponseService{ APPROVING("AP","申请中"), PASSS("PS", “已通过”), REJECT("RJ", “已拒绝”) }
1.4 包名
1. 包名必须小写
2. 包名尽量简洁,一个单词或缩写
3. 包名不能以数字开头,尽量只包含字母
4. 所有系统包命名须在:com.qihoo.finance,如:com.qihoo.finance.msf;maven依赖,groupId:com.qihoo.finance.xxx,artifactid: xxx-app, xxx-api等
1.5 类名
1. 大驼峰式命名,即单词首字母大写,如:UserService
2. 接口名不加前缀
3. 抽象类名以Abstract开头
4. 接口实现类名必须加上Impl,以Impl结尾,如:UserServiceImpl
2. 排版规范
1. 缩进必须用space,不能使用tab键,可以在eclipse或其他开发工具配置一个tab用4个space代替。
2. 单行字符数不超过120个
3. 开发工具建议使用intellij Idea,工具稳定性好,智能化,内存消耗稳定。
4. 其他?可以使用工具自动格式化功能
3. 注释规范
1. 类名,功能方法接口名称必须有注释
2. 复杂代码逻辑必须有注释
3. 代码注释不超过一行使用'//',超过一行使用‘/* */’
4. 代码提交规范
1. 原则上完成一个完整功能并自测无异常后,方可checkin代码,必须保证无编译报错
2. 提交代码必须写注释,能够完整描述本次提交变更的内容
例如:
缺陷/需求编号:(如果有)
修复/提交说明:修复自动获取实例编号并发启动获取失败问题/增加kryo序列化扩展,并设置为dubbo协议默认的序列化组件
5. 业务开发规范
5.1 包路径规范
1. 按公司域名,系统,子系统[模块]方式命名, 如:com.qihoo.msf.app.cust
2. 在子系统/模块下,业务开发一般包含以下几个包:
service 定义服务接口
domain/entity 定义实体类
Exception 定义异常类已经异常错误定义
dao 数据访问层
5.2 配置文件路径规范
配置文件统一规划在 src/main/resources 目录下,按照配置文件类型可以划分为一下几个子目录
spring spring相关配置文件,可以根据组件或模块拆分为几个文件,启动application.xml默认加载配置文件夹
properties 存放*.properties文件夹,与环境相关的配置在此类文件中,系统会初始化加载,测试生产放在特殊路径,与实例部署无关,以达到配置分离目的。
mybatis/mappings/子模块 Mybatis的Mapper文件,分模块存放
dubbo-service/[consumer/privider]-service 服务注册配置,consumer-service文件夹存放所有依赖的外部服务注册,按依赖系统分文件,如:loan-service.xml,customer-service.xml;provider-service文件夹存放实例提供的服务配置。
META-INF/dubbo/internal dubbo扩展包,对dubbo服务扩展在此注册,dubbo基于spi扩展。
5.3 MAVEN项目规范
1. maven命名规则,com.qihoo.系统名
2. 任何一个子系统的服务接口定义和服务实现必须划分为两个项目,如:loan-provider,loan-api
a. 服务接口项目主要包含以下几个模块:
service 接口定义类
domain/entity 接口相关实例定义
exception 异常定义
b. 服务实现项目主要包含:
业务逻辑实现
dao接口定义及实现
5.4 测试代码编写规范
1. 测试相关代码必须在 src/test/java 目录下
2. 测试相关的配置必须在 src/test/resources 目录下
3. 测试代码必须采用Junit方式编写,基础加载读取数据可以继承SpringTestCase即可
4. 测试案例必须有断言结果,如:Assert.assertEquals("Error20001", actualResult);
5.5 异常及错误编码规范
5.5.1 异常说明
1. 异常可分为业务异常和系统异常,系统异常的基类为SystemException, 业务异常的基类为BusinessException。父类为ServiceException
2. 业务逻辑校验异常,抛出BusinessException
3. msf服务体系内所有暴露服务接口定义抛出ServiceException,外部系统调用服务,通过状态码返回异常信息
3. 所有的错误代码采用Enum定义
5.5.2 错误代码命名规范
1. 系统异常代码由7位组成, 规则为:S+3位系统代码+3位数字编码,如:SAPV001 服务调用超时
2. 业务异常代码由7位代码组成,规则为:B+3位系统代码+3位数字, 如BAPV000 请求参数为空
3. enum常量命名格式为:模块代码+‘_’+异常变量,异常变量含义与中文一致,命名含义清晰,见字识义
4. 错误代码按模块连续编码,不同模块之间起始位数字不一样,如下图所示:
5.6 日志规范
1. 日志统一采用log4j2,是log4j的升级版本,性能是log4j的10倍,暂时采用默认的log4j
2. Logger的获取方式统一采用class的方式,使用dubbo提供的Logger,LoggerFactory类,如:
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
3. 业务关键环节必须打印日志
4. 外部接口调用必须打印日志,并统计接口调用耗时,以便统计趋势图
5. error级别以上的日志,必须记录关键业务信息,如方法的入参,错误发生时的变量现场,以便回溯追踪问题。
6. 禁止打印密码等敏感信息
5.7 事务规范
事务统一在spring配置文件中声明,按照方法匹配方式,服务开发只需要遵守命名规则即可
1. 不允许通过注解的方式定义事务,因事务源切换,事务控制机制等不易统一管理
2. 外部接口必须禁止在事务中
3. 禁止长事务,长事务切分为多个短事务,最好dml集中使用事务
4. 禁止嵌套事务,嵌套事务不易掌控
5. 事务必须显式声明,方法名匹配方式,‘*Trx’,‘\*NewTrx’,方法默认非事务运行
6. 系统设计规范
6.1 接口设计规范
1. 一切基于接口开发,提供业务逻辑服务必须提供接口
2. 接口方法参数超过3个,需要转换为dto属性,对象入参
3. 对外提供服务接口JSON返回结构[状态,错误代码,错误描述,数据]
4. Module内部服务接口类名以Service结尾,接口方法细粒度;对外提供接口类名以Facade结尾,接口方法定义粗粒度,禁止跨域调用DAO。
5. Service实现内部细粒度业务逻辑,Service不能跨域调用Service。
6. Façade层负责对外提供粗粒度功能方法,采用模板设计模式方法,实现仅包括:1. 入参校验;2.入参转换、清洗;3. 粗粒度业务功能流程控制(具体实现下沉到Service层,超过5个步骤应考虑下沉到Service);4.出参数据转换。
7. Facade调用:不同发布单元接口(Façade)调用,封装成内部Service方式,并实现入参出参记录,耗时统计等,系统内部只与内部Service交互;系统内不同待拆分模块之前接口调用Façade。
8. 尽量使用缓存:配置类数据使用内存(一级)缓存;业务类数据使用redis(二级)缓存
9. 服务必须设计为无状态服务,即,请求可以在任何实例完成处理
10. 服务设计为基于https短连接服务
11. 服务设计可并发执行、幂等性
12. 禁止使用Map作为入参出参,会增加接口复杂度,容易造成序列化、反序列化失败
13. 接口入参出参禁止删除字段、修改参数字段名,
14. 接口可以新增入参,出参;如果接口逻辑不兼容修改,必须使用版本号,并通知下游修改
15. 接口默认使用dubbo协议,单次请求入参、出参不能超过100k,否则必须更换hessian协议
6.2 领域设计规范
1. 服务类基于业务领域模块划分,划分原则可以与业务表对应
2. 尽量减少表连接,杜绝两个业务领域的表连接
3. 禁止大表连接(超过100w数据)
4. 禁止在SQL语句中使用1=1
5. 禁止批量数据用in关键词分组排序,即在In条件复杂查询语句
6. 更新操作条件必须有索引,通过explain确认执行计划走索引,尽量使用pk主键
7. 查询条件必须走索引
8. 原则上不允许应用使用delete语句,如有需要,必须记log,经过团队评审
9. 实体类与数据库表对应,api接口下的实体与dao层不一致,dao层实体命名为XxxEntity,防止修改内部实体类影响接口稳定性。
6.3 数据库设计规范
1. 禁止删除字段
2. 禁止更新字段名称,类型,减少长度;可以修改增加字段长度或备注
3. 数据库脚本支持提前上线,否则会影响热发布或者灰度发布
4. 每个领域实体表必须有一个领域主键驱动,便于信息查询
5. 查询结果按需读取,防止因字段过大造成数据传输开销
6. SQL命名准确,功能要单一,不能包含多种含义功能,维护会更复杂
6.4 redis缓存使用规范
1. 存放业务数据,必须设置ttl
6.5 内存缓存使用规范
1. 内存缓存只能存放开关类配置数据
7. main目录下的代码中不能包含以下代码,test目录下可以有
1. public staitc void main(String[] args)
2. System.out.println();
3. e.printStackTrace();
8. 输入输出流要再finally块中关闭
9. 定义变量用static final,而不是final static。
1 public static 必须加上final,防止被篡改
2 protected static 可以不用加上final
10. 泛型在定义变量时已经指定类型,实例化时不需要再指定泛型的类型。
//不建议的示例
Map<String, Object> map = new HashMap<String, Object>;
List<Map<String, Object>> resltList = new ArrayList<Map<String, Object>>();
//建议的示例
Map<String, Object> map = new HashMap<>;
List<Map<String, Object>> resltList = new ArrayList<>();
11. 不能直接catch throwable。因为throwable里包含OOM等异常,而此类异常是不需要捕获的。
12. 方法或者方法体,都不能直接抛出一个Exception,只能抛出一个自定义的Exception子类,例如SeriviceException
因为如果直接抛出Exception,调用该方法的调用者有可能无法识别异常是系统抛出的还是应用抛出的。