穿梭在银河的火箭队——代码规范、冲刺任务与计划
| 这个作业属于哪个课程 | 2022年福大-软件工程;软件工程实践-W班 |
|---|---|
| 这个作业要求在哪里 | 团队作业——站立式会议+alpha冲刺 |
| 这个作业的目标 | 明确团队代码规范、冲刺任务和冲刺计划 |
| 其它参考文献 | 百度JavaScript编码规范 阿里巴巴Java开发手册终极版v1.3.0 华为内部代码规范 |
目录
- 1 团队的代码规范
- 1.1 前端代码规范
- 1.1.1 代码风格
- 1.1.2 语言特性
- 1.1.3 浏览器环境
- 1.2 后端代码规范
- 1.2.1 编程规约
- 1.2.1.1 命名风格
- 1.2.1.2 常量定义
- 1.2.1.3 代码格式
- 1.2.1.4 OOP规约
- 1.2.1.5 控制语句
- 1.2.1.6 注释规约
- 1.2.1.7 其它
- 1.2.2 异常处理
- 1.2.3 单元测试
- 1.2.4 MySQL数据库
- 1.2.4.1 建表规约
- 1.2.4.2 索引规约
- 1.2.4.3 SQL语句
- 1.2.4.4 ORM映射
- 2 本次冲刺任务
- 2.1 前端
- 2.2 后端
- 2.3 整体
- 3 计划
- 3.1 开发计划
- 3.2 开发过程安排
- 3.3 人员分工安排
- 3.3.1 开发安排:
- 3.3.2 其他安排
- 4 代码仓库
1 团队的代码规范
1.1 前端代码规范
1.1.1 代码风格
文件
JavaScript 文件使用无
BOM的UTF-8编码。在文件结尾处,保留一个空行。
结构
缩进
使用
4个空格做为一个缩进层级,不允许使用2个空格 或tab字符。switch下的case和default必须增加一个缩进层级。
空格
二元运算符两侧必须有一个空格,一元运算符与操作对象之间不允许有空格。
用作代码块起始的左花括号
{前必须有一个空格。if / else / for / while / function / switch / do / try / catch / finally关键字后,必须有一个空格。在对象创建时,属性中的
:之后必须有空格,:之前不允许有空格。函数声明、具名函数表达式、函数调用中,函数名和
(之间不允许有空格。,和;前不允许有空格。如果不位于行尾,,和;后必须跟一个空格。在函数调用、函数声明、括号表达式、属性访问、
if / for / while / switch / catch等语句中,()和[]内紧贴括号部分不允许有空格。单行声明的数组与对象,如果包含元素,
{}和[]内紧贴括号部分不允许包含空格.行尾不得有多余的空格。
换行
每个独立语句结束后必须换行。
每行不得超过
120个字符。运算符处换行时,运算符必须在新行的行首。
在函数声明、函数表达式、函数调用、对象创建、数组创建、
for语句等场景中,不允许在,或;前换行。不同行为或逻辑的语句集,使用空行隔开,更易阅读。
在语句的行长度超过
120时,根据逻辑条件合理缩进。对于
if...else...、try...catch...finally等语句,推荐使用在}号后添加一个换行 的风格,使代码层次结构更清晰,阅读性更好。
语句
不得省略语句结束的分号。
在
if / else / for / do / while语句中,即使只有一行,也不得省略块{...}。函数定义结束不允许添加分号。
IIFE必须在函数表达式外添加(,非IIFE不得在函数表达式外添加(。
命名
变量使用Camel命名法。常量使用全部字母大写,单词间下划线分隔的命名方式。函数使用Camel命名法。函数的
参数使用Camel命名法。类使用Pascal命名法。类的
方法/属性使用Camel命名法。枚举变量使用Pascal命名法,枚举的属性使用全部字母大写,单词间下划线分隔的命名方式。命名空间使用Camel命名法。由多个单词组成的缩写词,在命名中,根据当前命名法和出现的位置,所有字母的大小写与首字母的大小写保持一致。
类名使用名词。函数名使用动宾短语。boolean类型的变量使用is或has开头。Promise对象用动宾短语的进行时表达。
注释
单行注释
必须独占一行。
//后跟一个空格,缩进与下一行被注释说明的代码一致。多行注释
避免使用
/*...*/这样的多行注释。有多行注释内容时,使用多个单行注释。文档化注释
为了便于代码阅读和自文档化,以下内容必须包含以
/**...*/形式的块注释中。文档注释前必须空一行。
自文档化的文档说明 what,而不是 how。
类型定义
类型定义都是以
{开始, 以}结束。对于基本类型 {string}, {number}, {boolean},首字母必须小写。
文件注释
文件顶部必须包含文件注释,用
@file标识文件说明。文件注释中可以用
@author标识开发者信息。
命名空间注释
命名空间使用
@namespace标识。
类注释
使用
@class标记类或构造函数。使用
@extends标记类的继承信息。使用包装方式扩展类成员时, 必须通过
@lends进行重新指向。类的属性或方法等成员信息不是
public的,应使用@protected或@private标识可访问性。
函数/方法注释
函数/方法注释必须包含函数说明,有参数和返回值时必须使用注释标识。
参数和返回值注释必须包含类型信息,且不允许省略参数的说明。
当函数是内部函数,外部不可访问时,可以使用
@inner标识。对 Object 中各项的描述, 必须使用
@param标识。重写父类方法时, 应当添加
@override标识。如果重写的形参个数、类型、顺序和返回值类型均未发生变化,可省略@param、@return,仅用@override标识,否则仍应作完整注释。
事件注释
必须使用
@event标识事件,事件参数的标识与方法描述的参数标识相同。在会广播事件的函数前使用
@fires标识广播的事件,在广播事件代码前使用@event标识事件。对于事件对象的注释,使用
@param标识,生成文档时可读性更好。
常量注释
常量必须使用
@const标记,并包含说明和类型信息。复杂类型注释
对于类型未定义的复杂结构的注释,可以使用
@typedef标识来定义。AMD 模块注释
AMD 模块使用
@module或@exports标识。对于已使用
@module标识为 AMD模块 的引用,在namepaths中必须增加module:作前缀。对于类定义的模块,可以使用
@alias标识构建函数。多模块定义时,可以使用
@exports标识各个模块。对于 exports 为 Object 的模块,可以使用
@namespace标识。对于 exports 为类名的模块,使用
@class和@exports标识。
1.1.2 语言特性
变量
变量、函数在使用前必须先定义。
每个
var只能声明一个变量。变量必须
即用即声明,不得在函数或其它形式的代码块起始位置统一声明所有变量。
条件
在 Equality Expression 中使用类型严格的
===。仅当判断null或undefined时,允许使用== null。尽可能使用简洁的表达式。
按执行频率排列分支的顺序。
如果函数或全局中的
else块后没有任何语句,可以删除else。
循环
不要在循环体中包含函数表达式,事先将函数提取到循环体外。
对循环内多次使用的不变值,在循环外用变量缓存。
类型
类型检测
类型检测优先使用
typeof。对象类型检测使用instanceof。null或undefined的检测使用== null。类型转换
转换成
string时,使用+ ''。转换成
number时,通常使用+。string转换成number,要转换的字符串结尾包含非数字并期望忽略时,使用parseInt。使用
parseInt时,必须指定进制。转换成
boolean时,使用!!。number去除小数点,使用Math.floor/Math.round/Math.ceil,不使用parseInt。
字符串
字符串开头和结束使用单引号
'。使用
数组或+拼接字符串。使用字符串拼接的方式生成HTML,需要根据语境进行合理的转义。
复杂的数据到视图字符串的转换过程,选用一种模板引擎。
对象
使用对象字面量
{}创建新Object。对象创建时,如果一个对象的所有
属性均可以不添加引号,建议所有属性不添加引号。对象创建时,如果任何一个
属性需要添加引号,则所有属性建议添加'。不允许修改和扩展任何原生对象和宿主对象的原型。
属性访问时,尽量使用
.。for in遍历对象时, 使用hasOwnProperty过滤掉原型中的属性。
数组
使用数组字面量
[]创建新数组,除非想要创建的是指定长度的数组。不因为性能的原因自己实现数组排序功能,尽量使用数组的
sort方法。清空数组使用
.length = 0。
函数
函数长度
一个函数的长度控制在
50行以内。参数设计
一个函数的参数控制在
6个以内。通过
options参数传递非数据输入型参数。
闭包
在适当的时候将闭包内大对象置为
null。使用
IIFE避免Lift 效应。
空函数
空函数不使用
new Function()的形式。对于性能有高要求的场合,建议存在一个空函数的常量,供多处使用共享。
9.面向对象
类的继承方案,实现时需要修正
constructor。属性在构造函数中声明,方法在原型中声明。
自定义事件的
事件名必须全小写。自定义事件只能有一个
event参数。如果事件需要传递较多信息,应仔细设计事件对象。设计自定义事件时,应考虑禁止默认行为。
动态特性
eval
避免使用直接
eval函数。尽量避免使用
eval函数。
动态执行代码。
使用
new Function执行动态代码。with
尽量不要使用
with。对象属性
避免修改外部传入的对象。
1.1.3 浏览器环境
模块化
AMD
使用
AMD作为模块定义。模块
id必须符合标准。
define
定义模块时不要指明
id和dependencies。使用
return来返回模块定义。
require
全局运行环境中,
require必须以async require形式调用。
DOM
元素获取
对于单个元素,尽可能使用
document.getElementById获取,避免使用document.all。对于多个元素的集合,尽可能使用
context.getElementsByTagName获取。其中context可以为document或其他元素。指定tagName参数为*可以获得所有子元素。遍历元素集合时,尽量缓存集合长度。如需多次操作同一集合,则应将集合转为数组。
样式获取
获取元素实际样式信息时,应使用
getComputedStyle或currentStyle。样式设置
尽可能通过为元素添加预定义的 className 来改变元素样式,避免直接操作 style 设置。
通过 style 对象设置元素样式时,对于带单位非 0 值的属性,不允许省略单位。
DOM 操作
操作
DOM时,尽量减少页面reflow。尽量减少
DOM操作。
DOM 事件
优先使用
addEventListener / attachEvent绑定事件,避免直接在 HTML 属性中或 DOM 的expando属性绑定事件处理。使用
addEventListener时第三个参数使用false。在没有事件自动管理的框架支持下,应持有监听器函数的引用,在适当时候(元素释放、页面卸载等)移除添加的监听器。
1.2 后端代码规范
1.2.1 编程规约
1.2.1.1 命名风格
代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。
代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。
类名使用 UpperCamelCase 风格,必须遵从驼峰形式,但以下情形例外:DO / BO / DTO / VO / AO
方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格,必须遵从驼峰形式。
例:localValue / getHttpMessage() / inputUserId
常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。
抽象类命名使用 Abstract 或 Base 开头;异常类命名使用 Exception 结尾;测试类命名以它要测试的类的名称开始,以 Test 结尾。
中括号是数组类型的一部分,数组定义如下:String[] args;
POJO 类中布尔类型的变量,都不要加 is,否则部分框架解析会引起序列化错误。
包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式,但是类名如果有复数含义,类名可以使用复数形式。
杜绝完全不规范的缩写,避免望文不知义。
为了达到代码自解释的目标,任何自定义编程元素在命名时,使用尽量完整的单词组合来表达其意。
如果模块、接口、类、方法使用了设计模式,在命名时体现出具体模式。
接口类中的方法和属性不要加任何修饰符号(public 也不要加),保持代码的简洁性,并加上有效的 Javadoc 注释。尽量不要在接口里定义变量,如果一定要定义变量,肯定是 与接口方法相关,并且是整个应用的基础常量。
接口和实现类的命名
对于 Service 和 DAO 类,基于 SOA 的理念,暴露出来的服务一定是接口,内部的实现类用 Impl 的后缀与接口区别。
例:CacheServiceImpl 实现 CacheService 接口。
如果是形容能力的接口名称,取对应的形容词做接口名(通常是–able 的形式)。
例:AbstractTranslator 实现 Translatable。
枚举类名建议带上 Enum 后缀,枚举成员名称需要全大写,单词间用下划线隔开。
各层命名规约:
Service/DAO 层方法命名规约
获取单个对象的方法用 get 做前缀。
获取多个对象的方法用 list 做前缀。
获取统计值的方法用 count 做前缀。
插入的方法用 save/insert 做前缀。
删除的方法用 remove/delete 做前缀。
修改的方法用 update 做前缀。
领域模型命名规约
数据对象:xxxDO,xxx 即为数据表名。
数据传输对象:xxxDTO,xxx 为业务领域相关的名称。
展示对象:xxxVO,xxx 一般为网页名称。
POJO 是 DO/DTO/BO/VO 的统称,禁止命名成 xxxPOJO。
1.2.1.2 常量定义
不允许任何魔法值(即未经定义的常量)直接出现在代码中。
long或者Long初始赋值时,使用大写的L,不能是小写的l,小写容易跟数字1混 淆,造成误解。
不要使用一个常量类维护所有常量,按常量功能进行归类,分开维护。
常量的复用层次有五层:跨应用共享常量、应用内共享常量、子工程内共享常量、包 内共享常量、类内共享常量。
跨应用共享常量:放置在二方库中,通常是client.jar中的constant目录下。
应用内共享常量:放置在一方库中,通常是modules中的constant目录下。
子工程内部共享常量:即在当前子工程的constant目录下。
包内共享常量:即在当前包下单独的constant目录下。
类内共享常量:直接在类内部private static final定义。
如果变量值仅在一个范围内变化,且带有名称之外的延伸属性,定义为枚举类。下面 正例中的数字就是延伸信息,表示星期几。
例:public Enum { M0NDAY(1), TUESDAY(2), WEDNESDAY©), THURSDAY(4), FRIDAY(5), SATURDAY(6), SUNDAY(7);}
1.2.1.3 代码格式
大括号的使用约定。如果是大括号内为空,则简洁地写成{}即可,不需要换行;如果 是非空代码块则:
左大括号前不换行。
左大括号后换行。
右大括号前换行。
右大括号后还有else等代码则不换行;表示终止的右大括号后必须换行。
左小括号和字符之间不出现空格;同样,右小括号和字符之间也不出现空格。
if/for/while/switch/do等保留字与括号之间都必须加空格。
任何二目、三目运算符的左右两边都需要加一个空格。 说明:运算符包括赋值运算符=、逻辑运算符&&、加减乘除符号等。
采用4个空格缩进,禁止使用tab字符。
说明:如果使用tab缩进,必须设置1个tab为4个空格。IDEA设置tab为4个空格时, 请勿勾选 Use tab character;而在 eclipse 中,必须勾选 insert spaces for tabs
例:(涉及1-5点)
public static void main(String[] args) {
//缩进4个空格
String say = "hello";
//运算符的左右必须有一个空格
int flag = 0;
//关键词if与括号之间必须有一个空格,括号内的f与左括号,0与右括号不需要空格
if (flag == 0) (
System.out.println(say);
)
//左大括号前加空格且不换行;左大括号后换行
if (flag == 1) (
System.out.println("world");
//右大括号前换行,右大括号后有else,不用换行
) else ( System.out.println("ok");
//在右大括号后直接结束,则必须换行
)
)
单行字符数限制不超过****120****个,超出需要换行
方法参数在定义和传入时,多个参数逗号后边必须加空格。
IDE的text file encoding设置为UTF-8
方法体内的执行语句组、变量的定义语句组、不同的业务逻辑之间或者不同的语义之间插入一个空行。相同业务逻辑和语义之间不需要插入空行。
1.2.1.4 OOP规约
避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可。
外部正在调用或者二方库依赖的接口,不允许修改方法签名,避免对接口调用方产生影响。
当一个类有多个构造方法,或者多个同名方法,这些方法应该按顺序放置在一起, 便于阅读。
类内方法定义顺序依次是:公有方法或保护方法 > 私有方法> getter/setter方法。
final可以声明类、成员变量、方法、以及本地变量,下列情况使用final关键字:
不允许被继承的类,如:String类。
不允许修改引用的域对象,如:POJO类的域变量。
不允许被重写的方法,如:POJO类的setter方法。
不允许运行过程中重新赋值的局部变量。
避免上下文重复使用一个变量,使用final描述可以强制重新定义一个变量,方便更好 地进行重构。
慎用Object的clone方法来拷贝对象。
类成员与方法访问控制从严:
如果不允许外部直接通过new来创建对象,那么构造方法必须是private。
工具类不允许有public或default构造方法。
类非static成员变量并且与子类共享,必须是protected。
类非static成员变量并且仅在本类使用,必须是private。
类static成员变量如果仅在本类使用,必须是private。
若是static成员变量,必须考虑是否为final。
类成员方法只供类内部调用,必须是private。
类成员方法只对继承类公开,那么限制为protectedo
1.2.1.5 控制语句
在一个switch块内,每个case要么通过break/return等来终止,要么注释说明程 序将继续执行到哪一个case为止;在一个switch块内,都必须包含一个default语句并且 放在最后,即使它什么代码也没有。
在if/else/for/while/do语句中必须使用大括号。即使只有一行代码,避免采用单行的编码方式:if (condition) statements;
表达异常的分支时,少用if-else方式
除常用方法(如getXxx/isXxx)等外,不要在条件判断中执行其它复杂的语句,将复 杂逻辑判断的结果赋值给一个有意义的布尔变量名,以提高可读性。
循环体中的语句要考量性能,以下操作尽量移至循环体外处理,如定义对象、变量、 获取数据库连接,进行不必要的try-catch操作(这个try-catch是否可以移至循环体外)。
接口入参保护,这种场景常见的是用于做批量操作的接口。
下列情形,需要进行参数校验:
调用频次低的方法。
执行时间开销很大的方法。此情形中,参数校验时间几乎可以忽略不计,但如果因为参 数错误导致中间执行回退,或者错误,那得不偿失。
需要极高稳定性和可用性的方法。
对外提供的开放接口,不管是RPC/API/HTTP接口。
敏感权限入口。
下列情形,不需要进行参数校验:
极有可能被循环调用的方法。但在方法说明里必须注明外部参数检查要求。
底层调用频度比较高的方法。毕竟是像纯净水过滤的最后一道,参数错误不太可能到底 层才会暴露问题。一般DAO层与Service层都在同一个应用中,部署在同一台服务器中,所 以DAO的参数校验,可以省略。
被声明成private只会被自己代码所调用的方法,如果能够确定调用方法的代码传入参 数已经做过检查或者肯定不会有问题,此时可以不校验参数。
1.2.1.6 注释规约
类、类属性、类方法的注释必须使用Javadoc规范,不得使用 // xxx方式。
所有的抽象方法(包括接口中的方法)必须要用Javadoc注释、除了返回值、参数、 异常说明外,还必须指出该方法做什么事情,实现什么功能。
所有的类都必须添加创建者和创建日期。
方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/* */注释,注意与代码对齐。
所有的枚举类型字段必须要有注释,说明每个数据项的用途。
与其“半吊子”英文来注释,不如用中文注释把问题说清楚。专有名词与关键字保持 英文原文即可。
代码修改的同时,注释也要进行相应的修改,尤其是参数、返回值、异常、核心逻辑 等的修改。
谨慎注释掉代码。在上方详细说明,而不是简单地注释掉。如果无用,则删除。 说明:代码被注释掉有两种可能性:1)后续会恢复此段代码逻辑。2)永久不用。前者如果没 有备注信息,难以知晓注释动机。后者建议直接删掉(代码仓库保存了历史代码)。
对于注释的要求:
能够准确反应设计思想和代码逻辑;
能够描述业务含 义,使别的程序员能够迅速了解到代码背后的信息。
好的命名、代码结构是自解释的,注释力求精简准确、表达到位。避免出现注释的 一个极端:过多过滥的注释,代码的逻辑一旦修改,修改注释是相当大的负担。
特殊注释标记,请注明标记人与标记时间。注意及时处理这些标记,通过标记扫描, 经常清理此类标记。线上故障有时候就是来源于这些标记处的代码。
待办事宜(TODO):(标记人,标记时间,[预计处理时间])
表示需要实现,但目前还未实现的功能。这实际上是一个Javadoc的标签,目前的Javadoc 还没有实现,但已经被广泛使用。只能应用于类,接口和方法(因为它是一个Javadoc标签)。
错误,不能工作(FIXME):(标记人,标记时间,[预计处理时间])
1.2.1.7 其它
在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。
velocity调用POJO类的属性时,建议直接使用属性名取值即可,模板引擎会自动按 规范调用POJO的getXxx(),如果是boolean基本数据类型变量(boolean命名不需要加is 前缀),会自动调用isXxx()方法。
后台输送给页面的变量必须加$!{var}—中间的感叹号。 说明:如果var = null或者不存在,那么${var}会直接显示在页面上。
注意Math . random()这个方法返回是double类型,注意取值的范围0<x<1 (能够 取到零值,注意除零异常),如果想获取整数类型的随机数,不要将x放大10的若干倍然后 取整,直接使用Random对象的nextInt或者nextLong方法。
获取当前毫秒数 System.currentTimeMillis();而不是 new Date() .getTime(); 说明:如果想获取更加精确的纳秒级时间值,使用System.nanoTime()的方式。在JDK8中, 针对统计时间等场景,推荐使用Instant类。
不要在视图模板中加入任何复杂的逻辑。
任何数据结构的构造或初始化,都应指定大小,避免数据结构无限增长吃光内存。
及时清理不再使用的代码段或配置信息。
1.2.2 异常处理
Java类库中定义的一类RuntimeException可以通过预先检查进行规避,而不应该 通过 catch 来处理。
对大段代码进行try-catch,这是不负责任的表现。catch时请分清稳定代码和非稳 定代码,稳定代码指的是无论如何不会出错的代码。对于非稳定代码的catch尽可能进行区分 异常类型,再做对应的异常处理。
捕获异常是为了处理它,不要捕获了却什么都不处理而抛弃之,如果不想处理它,请 将该异常抛给它的调用者。最外层的业务使用者,必须处理异常,将其转化为用户可以理解的 内容。
有try块放到了事务代码中,catch异常后,如果需要回滚事务,一定要注意手动回 滚事务。
finally块必须对资源对象、流对象进行关闭,有异常也要做try-catch。
不能在finally块中使用return,finally块中的return返回后方法结束执行,不 会再执行try块中的return语句。
捕获异常与抛异常,必须是完全匹配,或者捕获异常是抛异常的父类。 说明:如果预期对方抛的是绣球,实际接到的是铅球,就会产生意外情况。
方法的返回值可以为null,不强制返回空集合,或者空对象等,必须添加注释充分 说明什么情况下会返回null值。调用方需要进行null判断防止NPE问题。
防止NPE,是程序员的基本修养,注意NPE产生的场景:
返回类型为基本数据类型,return包装数据类型的对象时,自动拆箱有可能产生NPE。
数据库的查询结果可能为null。
集合里的元素即使isNotEmpty,取出的数据元素也可能为null。
远程调用返回对象时,一律要求进行空指针判断,防止NPE。
对于Session中获取的数据,建议NPE检查,避免空指针。
级联调用obj.getA().getB().getC(); 一连串调用,易产生NPE。
定义时区分unchecked / checked异常,避免直接抛出new RuntimeException(), 更不允许抛出Exception或者Throwable,应使用有业务含义的自定义异常。推荐业界已定义 过的自定义异常,如:DAOException / ServiceException 等。
避免出现重复的代码。
1.2.3 单元测试
好的单元测试必须遵守AIR原则。
A: Automatic (自动化)
I: Independent (独立性)
R: Repeatable (可重复)
单元测试应该是全自动执行的,并且非交互式的。测试框架通常是定期执行的,执行 过程必须完全自动化才有意义。输出结果需要人工检查的测试不是一个好的单元测试。单元测 试中不准使用System.out来进行人肉验证,必须使用assert来验证。
保持单元测试的独立性。为了保证单元测试稳定可靠且便于维护,单元测试用例之间 决不能互相调用,也不能依赖执行的先后次序。
单元测试是可以重复执行的,不能受到外界环境的影响。
对于单元测试,要保证测试粒度足够小,有助于精确定位问题。单测粒度至多是类级 另U, 一般是方法级别。
核心业务、核心应用、核心模块的增量代码确保单元测试通过。
单元测试代码必须写在如下工程目录:src/test/java,不允许写在业务代码目录下。 说明:源码构建时会跳过此目录,而单元测试框架默认是扫描此目录。
单元测试的基本目标:语句覆盖率达到70%;核心模块的语句覆盖率和分支覆盖率都 要达到100%
编写单元测试代码遵守BCDE原则,以保证被测试模块的交付质量。
B: Border,边界值测试,包括循环边界、特殊取值、特殊时间点、数据顺序等。
C: Correct,正确的输入,并得到预期的结果。
D: Design,与设计文档相结合,来编写单元测试。
E: Error,强制错误信息输入(如:非法数据、异常流程、非业务允许输入等),并得 到预期的结果。
对于数据库相关的查询,更新,删除等操作,不能假设数据库里的数据是存在的, 或者直接操作数据库把数据插入进去,请使用程序插入或者导入数据的方式来准备数据。
和数据库相关的单元测试,可以设定自动回滚机制,不给数据库造成脏数据。或者 对单元测试产生的数据有明确的前后缀标识。
对于不可测的代码建议做必要的重构,使代码变得可测,避免为了达到测试要求而 书写不规范测试代码。
在设计评审阶段,开发人员需要和测试人员一起确定单元测试范围,单元测试最好 覆盖所有测试用例(UC)。
单元测试作为一种质量保障手段,不建议项目发布后补充单元测试用例,建议在项 目提测前完成单元测试。
为了更方便地进行单元测试,业务代码应避免以下情况:
构造方法中做的事情过多。
存在过多的全局变量和静态方法。
存在过多的外部依赖。
存在过多的条件语句。
1.2.4 MySQL数据库
1.2.4.1 建表规约
表达是与否概念的字段,必须使用is_xxx的方式命名,数据类型是unsigned tinyint (1表示是,0表示否)。
表名、字段名必须使用小写字母或数字,禁止出现数字开头,禁止两个下划线中间只 出现数字。数据库字段名的修改代价很大,因为无法进行预发布,所以字段名称需要慎重考虑。
表名不使用复数名词。
禁用保留字,如desc、range、match、delayed等,请参考MySQL官方保留字。
主键索引名为pk_字段名;唯一索引名为uk_字段名;普通索引名则为idx_字段名。 说明:pk_ 即 primary key; uk_ 即 unique key; idx_ 即 index 的简称。
小数类型为decimal,禁止使用float和double。
如果存储的字符串长度几乎相等,使用char定长字符串类型。
varchar是可变长字符串,不预先分配存储空间,长度不要超过5000,如果存储长 度大于此值,定义字段类型为text,独立出来一张表,用主键来对应,避免影响其它字段索 引效率。
表必备三字段:id, gmt_create, gmt_modified。
表的命名最好是加上“业务名称_表的作用”。
库名与应用名称尽量一致。
如果修改字段含义或对字段表示的状态追加时,需要及时更新字段注释。
字段允许适当冗余,以提高查询性能,但必须考虑数据一致。冗余字段应遵循:
不是频繁修改的字段。
不是varchar超长字段,更不能是text字段。
单表行数超过500万行或者单表容量超过2GB,才推荐进行分库分表。
合适的字符存储长度,不但节约数据库表空间、节约索引存储,更重要的是提升检 索速度。
1.2.4.2 索引规约
业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引。
超过三个表禁止join。需要join的字段,数据类型必须绝对一致;多表关联查询时, 保证被关联的字段需要有索引。
在varchar字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据 实际文本区分度决定索引长度即可。
页面搜索严禁左模糊或者全模糊,如果需要请走搜索引擎来解决。
如果有order by的场景,请注意利用索引的有序性。order by最后的字段是组合 索引的一部分,并且放在索引组合顺序的最后,避免出现file_sort的情况,影响查询性能。
利用覆盖索引来进行查询操作,避免回表。
利用延迟关联或者子查询优化超多分页场景。
SQL性能优化的目标:至少要达到range级别,要求是ref级别,如果可以是consts 最好。
建组合索引的时候,区分度最高的在最左边。
防止因字段类型不同造成的隐式转换,导致索引失效。
创建索引时避免有如下极端误解:
宁滥勿缺。认为一个查询就需要建一个索引。
宁缺勿滥。认为索引会消耗空间、严重拖慢更新和新增速度。
抵制惟一索引。认为业务的惟一性一律需要在应用层通过“先查后插”方式解决。
1.2.4.3 SQL语句
不要使用count(列名)或count(常量)来替代count(),count()是SQL92定义的 标准统计行数的语法,跟数据库无关,跟NULL和非NULL无关。
count(distinct col)计算该列除NULL之外的不重复行数,注意count(distinct col1, col2)如果其中一列全为NULL,那么即使另一列有不同的值,也返回为0。
当某一列的值全是NULL时,count(col)的返回结果为0,但sum(col)的返回结果为 NULL,因此使用sum()时需注意NPE问题。
使用ISNULL()来判断是否为NULL值。
在代码中写分页查询逻辑时,若count为0应直接返回,避免执行后面的分页语句。
不得使用外键与级联,一切外键概念必须在应用层解决。
禁止使用存储过程,存储过程难以调试和扩展,更没有移植性。
数据订正时,删除和修改记录时,要先select,避免出现误删除,确认无误才能执 行更新语句。
in操作能避免则避免,若实在避免不了,需要仔细评估in后边的集合元素数量,控 制在1。。。个之内。
如果有全球化需要,所有的字符存储与表示,均以utf-8编码,注意字符统计函数 的区别。
如果需要存储表情,那么选择utfmb4来进行存储,注意它与utf-8编码的区别。
TRUNCATE TABLE比DELETE速度快,且使用的系统和事务日志资源少,但TRUNCATE 无事务且不触发trigger,有可能造成事故,故不建议在开发代码中使用此语句。
1.2.4.4 ORM映射
在表查询中,一律不要使用星号作为查询的字段列表,需要哪些字段必须明确写明。
POJO类的布尔属性不能加is,而数据库字段必须加is_,要求在resultMap中进行 字段与属性之间的映射。
不要用resultclass当返回参数,即使所有类属性名与数据库字段一一对应,也需 要定义;反过来,每一个表也必然有一个与之对应。
sql.xml配置参数使用:#{},#param#不要使用${}此种方式容易出现SQL注入。
iBATIS 自带的 queryForList(String statementName, int start, int size)不推 荐使用。
不允许直接拿HashMap与Hashtable作为查询结果集的输出。
更新数据表记录时,必须同时更新记录对应的gmt_modified字段值为当前时间。
不要写一个大而全的数据更新接口。传入为POJO类,不管是不是自己的目标更新字 段,都进行叩date table set c1=value1,c2=value2, c3=value3;这是不对的。执行 SQL 时,不要更新无改动的字段,一是易出错;二是效率低;三是增加binlog存储。
@Transactional事务不要滥用。事务会影响数据库的QPS,另外使用事务的地方需 要考虑各方面的回滚方案,包括缓存回滚、搜索引擎回滚、消息补偿、统计修正等。
<isEqual>中的compareValue是与属性值对比的常量,一般是数字,表示相等时带 上此条件;<isNotEmpty>表示不为空且不为null时执行;<isNotNull>表示不为null值时 执行。
2 本次冲刺任务
2.1 前端
完成前台对应的前端开发(小组项目分为前台和后台)
进行相应功能的测试
2.2 后端
完成前台对应的后端开发
进行相应功能的测试
2.3 整体
本次项目前台的各功能模块划分如下
登录模块
地图模块
自习模块
单机自习模块
联机自习模块
个人中心模块
展示修改个人资料界面
自习数据概览模块
在完成制作与整体测试后,将项目部署至服务器上
3 计划
3.1 开发计划
| 时间 | 天数 | 安排 |
|---|---|---|
| 4.26 | 1天 | 编写置顶集合随笔 编写代码规范、冲刺任务与计划 进行开发前的准备 每个组员拉取一条自己有关的分支,并做到正常运行 每个人登录Teambition在自己的任务下面将这次的任务细化为若干个子任务,方便做燃尽图 |
| 4.27-5.10 | 9天 | 完成各模块代码编写 |
| 5.11 | 1天 | 完成整体测试 |
| 5.12 | 1天 | 部署,发布alpha版本 编写测试随笔 |
| 5.13 | 1天 | 编写冲刺总结随笔 制作答辩PPT |
3.2 开发过程安排
每天举行站立式会议并拍照
每日汇报:每天晚上10点前完成填写q群的在线文档
每天晚上11点负责人要负责合并代码到dev分支中
每天晚上11点前发布冲刺随笔
3.3 人员分工安排
3.3.1 开发安排:
我们小组将各模块(详见本次冲刺任务部分介绍)参照照功能及开发难度的合理性划分为几个部分,然后由小组成员自行选择进行开发。最终,我们小组各部分的划分及分工如下所示:
| 序号 | 前端or后端 | 负责内容 | 人员 |
|---|---|---|---|
| 1 | 前端 | 前台登录模块 个人中心模块——展示修改个人资料 | 李鸿翔 |
| 2 | 前端 | 个人中心模块——自习数据概览模块 | 李慧子 |
| 3 | 前端 | 地图模块 | 黄子龙 |
| 4 | 前端 | 自习模块——单机自习模块 | 王亚娇 |
| 5 | 前端 | 自习模块——联机自习模块 | 陈志霖 |
| 6 | 后端 | 前台登录模块接口 个人信息接口 | 詹鹏翔 |
| 7 | 后端 | 自习数据概览模块接口 | 陈玮鑫 |
| 8 | 后端 | 教室查询接口 推荐教室接口 | 王凯达 |
| 9 | 后端 | 白应用软件接口 添加自习记录接口 | 黄依灵 |
| 10 | 后端 | 联机自习接口 | 陈少峰 |

4月28日根据项目情况修改分工为:
| 序号 | 工作方向 | 负责内容 | 人员 |
|---|---|---|---|
| 1 | 前端 | 前台登录模块 个人中心模块——展示修改个人资料 | 李鸿翔 |
| 2 | 前端 | 个人中心模块——自习数据概览模块 | 李慧子 |
| 3 | 前端 | 地图模块 | 黄子龙 |
| 4 | 前端 | 自习模块——单机自习模块 | 王亚娇 |
| 5 | 前端 | 自习模块——联机自习模块 | 陈志霖 |
| 6 | 后端 | 前台登录模块接口,个人信息接口 教室查询接口,推荐教室接口 | 詹鹏翔 |
| 7 | 后端 | 自习数据概览模块接口 | 陈玮鑫 |
| 8 | 后端 | 白应用软件接口 添加自习记录接口 | 黄依灵 |
| 9 | 后端 | 联机自习接口 | 陈少峰 |
| 10 | 文职和汇报 | 8篇冲刺随笔,1篇测试随笔,1篇冲刺总结随笔 ,其他工作,汇报 | 王凯达 |
tips:
由于各模块的开发可能存在部分的代码复用问题,在开发过程中由相关部分的负责人员自行讨论,根据具体情况灵活调整
前后端开发过程中有不确定、不明白的地方时,请联系对应部分的开发人员
3.3.2 其他安排
| 职责 | 具体内容 | 人员 |
|---|---|---|
| 前端负责人 | 合并代码,检查每个人的代码并微调,解答疑惑 | 王亚娇 |
| 后端负责人 | 合并代码,检查每个人的代码并微调,解答疑惑 | 詹鹏翔 |
| 编写博客 | 1篇置顶集合随笔,代码规范、冲刺任务与计划随笔,10篇冲刺随笔,1篇测试随笔,1篇冲刺总结随笔 | 李慧子 |
| 课堂演示、答辩 | 汇报 | 王凯达 |
| 课堂演示、答辩 | 制作PPT | 黄依灵 |
4月28日根据项目情况修改分工为:
| 职责 | 具体内容 | 人员 |
|---|---|---|
| 前端负责人 | 合并代码,检查每个人的代码并微调,解答疑惑 | 王亚娇 |
| 后端负责人 | 合并代码,检查每个人的代码并微调,解答疑惑 | 詹鹏翔 |
| 编写博客 | 1篇置顶集合随笔,代码规范、冲刺任务与计划随笔,2篇冲刺随笔 | 李慧子 |
| 课堂演示 | 制作PPT | 黄依灵 |
4 代码仓库
相关推荐
【工业自动化】欧姆龙PLC产品线与编程软件体系详解:基于西门子工程师视角的选型指导与避坑指南
内容概要:本文详细解析了欧姆龙PLC的产品线、编程软件体系、通信架构及选型策略,重点从西门子工程师视角出发,对比两者的定位差异与技术路径。文章明确指出欧姆龙存在两套不兼容的系统:传统的C系列(CP/CJ/CS)使用CX-Programmer软件和绝对地址编程,适用于单机设备与老线改造;新型Sysmac平台(NJ/NX/NY)采用Sysmac Studio集成开发环境,支持IEC 61131-3标签变量、EtherCAT运动控制和多领域一体化控制,代表当前技术高地。同时梳理了FINS、CompoWay/F、EtherCAT、EtherNet/IP等多层通信协议的区别,并列出从西门子转型易踩的八大误区,提供清晰的选型决策路径。; 适合人群:具备一定工业自动化背景,熟悉西门子PLC体系,正在转向或需要维护欧姆龙系统的工程师,尤其是从事设备选型、系统集成与产线升级的研发和技术人员。; 使用场景及目标:①帮助西门子背景工程师快速建立对欧姆龙双平台的认知框架;②指导正确选用CP/CJ/NJ/NX系列及配套软件;③避免在通信接口、地址体系、软件版本等方面出现典型错误;④实现老旧系统向新平台平滑迁移。; 阅读建议:此资源强调“先框架后细节”,建议读者先掌握三大平台分流和软件对应关系,再深入具体型号参数。特别注意2026年10月新版Sysmac Studio与CX-One对CJ3M系列的双向支持这一关键更新,在实际项目中需严格核对控制器固件与软件版本匹配性,防止因版本不兼容导致无法连接。
地级市到杭州北京深圳的球面距离.-最新出炉zip
一、资源特点 全新力作:今年精心打造,人工细细打磨,品质上乘。 权威精准:数据来源,准确靠谱,值得信赖。 品质无忧:绝无数据造假,品质有保障,放心使用。 二、适用人群 学生:在校专科生、本科生、研究生,助力学业各个环节。 教研人员:大学教师和学术科研工作者,为教学科研添力。 三、适用专业 社科经济:经济学、社会学专业适用。 规划管理:地理学、城市规划,以及商业、工商管理专业皆可使用。 [特别说明]相关资源数据已全部上传至网盘。 由于纯手工分享粘贴链接和提取码,不排除有极少提取码或者链接出现差错(或内容与标题对不上),若遇到这种情况,不要着急,请私信博主,将会第一时间更正补链接!
openeuler配置
openeuler系统环境配置管理
产业园区运营负责人如何提升园区内科技成果引进与落地的匹配效率?.docx
科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。
CISP-CSE注册云安全工程师备考资源包
CISP-CSE注册云安全工程师备考资源包


