142
社区成员
发帖
与我相关
我的任务
分享| 这个作业属于哪个课程 | 2022年福大-软件工程;软件工程实践-W班 |
|---|---|
| 这个作业要求在哪里 | 团队作业——站立式会议+alpha冲刺 |
| 这个作业的目标 | 明确团队代码规范、冲刺任务和冲刺计划 |
| 其它参考文献 | 百度JavaScript编码规范 阿里巴巴Java开发手册终极版v1.3.0 华为内部代码规范 |
文件
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 标识。
变量
变量、函数在使用前必须先定义。
每个 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。
对象属性
避免修改外部传入的对象。
模块化
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。
在没有事件自动管理的框架支持下,应持有监听器函数的引用,在适当时候(元素释放、页面卸载等)移除添加的监听器。
代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。
代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。
类名使用 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。
不允许任何魔法值(即未经定义的常量)直接出现在代码中。
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);}
大括号的使用约定。如果是大括号内为空,则简洁地写成{}即可,不需要换行;如果 是非空代码块则:
左大括号前不换行。
左大括号后换行。
右大括号前换行。
右大括号后还有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
方法体内的执行语句组、变量的定义语句组、不同的业务逻辑之间或者不同的语义之间插入一个空行。相同业务逻辑和语义之间不需要插入空行。
避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可。
外部正在调用或者二方库依赖的接口,不允许修改方法签名,避免对接口调用方产生影响。
当一个类有多个构造方法,或者多个同名方法,这些方法应该按顺序放置在一起, 便于阅读。
类内方法定义顺序依次是:公有方法或保护方法 > 私有方法> 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
在一个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只会被自己代码所调用的方法,如果能够确定调用方法的代码传入参 数已经做过检查或者肯定不会有问题,此时可以不校验参数。
类、类属性、类方法的注释必须使用Javadoc规范,不得使用 // xxx方式。
所有的抽象方法(包括接口中的方法)必须要用Javadoc注释、除了返回值、参数、 异常说明外,还必须指出该方法做什么事情,实现什么功能。
所有的类都必须添加创建者和创建日期。
方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/* */注释,注意与代码对齐。
所有的枚举类型字段必须要有注释,说明每个数据项的用途。
与其“半吊子”英文来注释,不如用中文注释把问题说清楚。专有名词与关键字保持 英文原文即可。
代码修改的同时,注释也要进行相应的修改,尤其是参数、返回值、异常、核心逻辑 等的修改。
谨慎注释掉代码。在上方详细说明,而不是简单地注释掉。如果无用,则删除。 说明:代码被注释掉有两种可能性:1)后续会恢复此段代码逻辑。2)永久不用。前者如果没 有备注信息,难以知晓注释动机。后者建议直接删掉(代码仓库保存了历史代码)。
对于注释的要求:
能够准确反应设计思想和代码逻辑;
能够描述业务含 义,使别的程序员能够迅速了解到代码背后的信息。
好的命名、代码结构是自解释的,注释力求精简准确、表达到位。避免出现注释的 一个极端:过多过滥的注释,代码的逻辑一旦修改,修改注释是相当大的负担。
特殊注释标记,请注明标记人与标记时间。注意及时处理这些标记,通过标记扫描, 经常清理此类标记。线上故障有时候就是来源于这些标记处的代码。
待办事宜(TODO):(标记人,标记时间,[预计处理时间])
表示需要实现,但目前还未实现的功能。这实际上是一个Javadoc的标签,目前的Javadoc 还没有实现,但已经被广泛使用。只能应用于类,接口和方法(因为它是一个Javadoc标签)。
错误,不能工作(FIXME):(标记人,标记时间,[预计处理时间])
在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。
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类。
不要在视图模板中加入任何复杂的逻辑。
任何数据结构的构造或初始化,都应指定大小,避免数据结构无限增长吃光内存。
及时清理不再使用的代码段或配置信息。
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 等。
避免出现重复的代码。
好的单元测试必须遵守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)。
单元测试作为一种质量保障手段,不建议项目发布后补充单元测试用例,建议在项 目提测前完成单元测试。
为了更方便地进行单元测试,业务代码应避免以下情况:
构造方法中做的事情过多。
存在过多的全局变量和静态方法。
存在过多的外部依赖。
存在过多的条件语句。
表达是与否概念的字段,必须使用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,才推荐进行分库分表。
合适的字符存储长度,不但节约数据库表空间、节约索引存储,更重要的是提升检 索速度。
业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引。
超过三个表禁止join。需要join的字段,数据类型必须绝对一致;多表关联查询时, 保证被关联的字段需要有索引。
在varchar字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据 实际文本区分度决定索引长度即可。
页面搜索严禁左模糊或者全模糊,如果需要请走搜索引擎来解决。
如果有order by的场景,请注意利用索引的有序性。order by最后的字段是组合 索引的一部分,并且放在索引组合顺序的最后,避免出现file_sort的情况,影响查询性能。
利用覆盖索引来进行查询操作,避免回表。
利用延迟关联或者子查询优化超多分页场景。
SQL性能优化的目标:至少要达到range级别,要求是ref级别,如果可以是consts 最好。
建组合索引的时候,区分度最高的在最左边。
防止因字段类型不同造成的隐式转换,导致索引失效。
创建索引时避免有如下极端误解:
宁滥勿缺。认为一个查询就需要建一个索引。
宁缺勿滥。认为索引会消耗空间、严重拖慢更新和新增速度。
抵制惟一索引。认为业务的惟一性一律需要在应用层通过“先查后插”方式解决。
不要使用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,有可能造成事故,故不建议在开发代码中使用此语句。
在表查询中,一律不要使用星号作为查询的字段列表,需要哪些字段必须明确写明。
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值时 执行。
完成前台对应的前端开发(小组项目分为前台和后台)
进行相应功能的测试
完成前台对应的后端开发
进行相应功能的测试
本次项目前台的各功能模块划分如下
登录模块
地图模块
自习模块
单机自习模块
联机自习模块
个人中心模块
展示修改个人资料界面
自习数据概览模块
在完成制作与整体测试后,将项目部署至服务器上
| 时间 | 天数 | 安排 |
|---|---|---|
| 4.26 | 1天 | 编写置顶集合随笔 编写代码规范、冲刺任务与计划 进行开发前的准备 每个组员拉取一条自己有关的分支,并做到正常运行 每个人登录Teambition在自己的任务下面将这次的任务细化为若干个子任务,方便做燃尽图 |
| 4.27-5.10 | 9天 | 完成各模块代码编写 |
| 5.11 | 1天 | 完成整体测试 |
| 5.12 | 1天 | 部署,发布alpha版本 编写测试随笔 |
| 5.13 | 1天 | 编写冲刺总结随笔 制作答辩PPT |
每天举行站立式会议并拍照
每日汇报:每天晚上10点前完成填写q群的在线文档
每天晚上11点负责人要负责合并代码到dev分支中
每天晚上11点前发布冲刺随笔
我们小组将各模块(详见本次冲刺任务部分介绍)参照照功能及开发难度的合理性划分为几个部分,然后由小组成员自行选择进行开发。最终,我们小组各部分的划分及分工如下所示:
| 序号 | 前端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:
由于各模块的开发可能存在部分的代码复用问题,在开发过程中由相关部分的负责人员自行讨论,根据具体情况灵活调整
前后端开发过程中有不确定、不明白的地方时,请联系对应部分的开发人员
| 职责 | 具体内容 | 人员 |
|---|---|---|
| 前端负责人 | 合并代码,检查每个人的代码并微调,解答疑惑 | 王亚娇 |
| 后端负责人 | 合并代码,检查每个人的代码并微调,解答疑惑 | 詹鹏翔 |
| 编写博客 | 1篇置顶集合随笔,代码规范、冲刺任务与计划随笔,10篇冲刺随笔,1篇测试随笔,1篇冲刺总结随笔 | 李慧子 |
| 课堂演示、答辩 | 汇报 | 王凯达 |
| 课堂演示、答辩 | 制作PPT | 黄依灵 |
4月28日根据项目情况修改分工为:
| 职责 | 具体内容 | 人员 |
|---|---|---|
| 前端负责人 | 合并代码,检查每个人的代码并微调,解答疑惑 | 王亚娇 |
| 后端负责人 | 合并代码,检查每个人的代码并微调,解答疑惑 | 詹鹏翔 |
| 编写博客 | 1篇置顶集合随笔,代码规范、冲刺任务与计划随笔,2篇冲刺随笔 | 李慧子 |
| 课堂演示 | 制作PPT | 黄依灵 |