Contents

项目开发守则

project_rule

本项目是南京大学软件学院 2018 级软件工程与计算 III 课程设计项目

1. 总体规约

  1. 开发工具:Intellij IDEA
  2. 数据库管理工具:Navicat
  3. 项目文档和沟通管理:飞书
  4. 项目版本管理工具:git
  5. 接口管理工具:Apifox

2. 编程规约

Craftsmanship and the Problem of Productivity: Secrets for Going Fast without Making a Mess

2.1 代码规范

JAVA 代码规范参照 IDEA 插件 Alibaba Java Coding Guidelines,尽量减少 warning,不能存在 error

2.1.1 软工设计原则

  1. 单一职责原则

    对类来说,一个类应该只负责一项职责。如果一个类负责两个职责,可能存在职责 1 变化,引起职责 2 的变化情况。可以基于抽象逻辑,或者业务逻辑对类进行细化。

  2. 接口隔离原则

    客户端不应该依赖它不需要的接口,一个类对另外一个类的依赖,应该建立在最小的接口上。

  3. 依赖倒置原则

    高层模块不应该依赖低层模块,两者应依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象;中心思想是面向接口编程。

  4. 里氏替换原则

    如果将所有类型为 T1 的对象 O1 都替换成类型 T2de 对象 O2,程序的行为不发生改变。那么类型 T2 是类型 T1 的子类型。换句话说说有引用基类的地方必须能透明的使用其子类的对象。

  5. 开闭原则

    在代码结构的设计设计时,应该考虑对扩展开放,对修改关闭,抽象思维搭建结构,具体实现扩展细节。

  6. 迪米特法则

    一个类对自己依赖的类知道的越要越好。也就是说,对于依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供的 public 方法,不对外开放任何信息

2.2 注释规范

  1. 代码是用来读的,代码的意图应该由代码自身阐述,优先考虑写更可读的代码
  2. 代码意图明显的情况下,不要加注释重复说明
  3. 临时注释标记:TODO, FIXME, OPTIMIZE, REVIEW
  4. 注释应该随着代码更新

2.2.1 必须要写注释的情况

为什么,而非是什么

  1. 纲要性的注释:简洁清晰的描述一个文件、类或一个流程
  2. 复杂的业务逻辑、算法
  3. 代码的作用不直观时,解释这样做的原因
  4. 存在多种可选方案时,解释这样选择的原因
  5. 因为某些限制导致代码不一致、不优雅、存在副作用时,注明原因及后果
  6. 参考了外部资料时,要注明链接方便查看
  7. 所有的抽象方法

3. 日志规约

使用 slf4j 框架记录项目运行日志,不要用系统原生 log

4. 测试规约

AIR 原则:单元测试在运行时,要感觉像 AIR 一样并不存在 –Automatic, Independent, Repeatable

5. 安全规约

  1. 用户请求传入的任何参数必须做有效性验证,忽略参数校验可能导致
    1. page size 过大导致内存溢出
    2. 恶意 order 导致数据库安全风险或慢查询
  2. 用户敏感数据必须要放在数据库中,账号密码等强安全数据需要使用彩虹表等进行加密处理
  3. 用户传入的 SQL 参数严格使用参数绑定或 metadata 字段限定,防止 SQL 注入,禁止字符串拼接 SQL 访问数据库 (还记得华为的 drop database 吗)
  4. 隶属于用户个人的页面或者功能必须进行权限控制校验
  5. 在使用平台资源 (短信、邮件、电话等) 必须实现防重复限制,如数量限制、疲劳度控制、验证码校验等,避免被滥用

6. 数据库规约

6.1 建表规约

  1. 表达是否概念的字段必须使用 is_xxx 方式命名,数据类型是 unsigned tinyint(1 表示是,0 表示否)
  2. 如果用字符串来表示有限个状态 (例如 status),必须在后端使用枚举类型传入参数
  3. 表名、字段名必须使用小写字母或数字,禁止数字开头,禁止两个下划线间只有数字。数据库字段名的修改代价很大,字段名的命名需要慎重考虑。
    • Mysql 在 Windows 下不区分大小写,而 Linux 下默认区分,因此不允许出现任何大写字母
  4. 表名不使用复数名词
    • 表名应该仅仅表示表里面的实体内容,不应该表示实体数量,对应于 DO 类名也是单数形式,符合表达习惯
  5. 小数类型为 decimal,禁止使用 float 和 double
    • float 和 double 在存储的时候,存在精度损失的问题,很可能在值的比较时,得到不正确的结果。如果存储的数据范围超过 decimal 的范围,建议将数据拆成整数和小数分开存储
  6. 如果存储的字符串长度几乎相等,使用 char 定长字符串类型
  7. varchar 是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索引效率
  8. 表必备三字段:id, gmt_create, gmt_modified。
    • 其中 id 必为主键,类型为 unsigned bigint、单表时自增、步长为 1。gmt_create, gmt_modified 的类型均为 timestamp 类型,前者现在时表示主动创建,后者过去分词表示被动更新
  9. 表的命名最好以 业务名称_表的作用 作为开头
  10. 字段允许适当冗余,以提高查询性能,但必须考虑数据一致。冗余字段应遵循
    1. 不是频繁修改的字段。
    2. 不是 varchar 超长字段,更不能是 text 字段。
  11. 所有字符的存储与表示都要以 utf-8 编码
    • 字符统计函数在不同编码有区别,因此统一编码

6.2 SQL 规范

  1. 不要使用 count(列名)count(常量) 来替代 count(*)count 是统计行数的语法,和数据库无关,和 NULL 非 NULL 无关
    • count(*) 会统计值为 NULL 的行,而 count(列名) 不会统计为 NULL 的行
  2. 使用 ISNULL() 来判断是否为 NULL,因为 NULL<>NULL, NULL=NULL, NULL<>1 的结果都是 NULL 而不是 true

7. 版本控制规约

乱动 origin/main 者,狗头打掉!

git团队实践 阮一峰git规范

7.1 Commit 规则

  1. commit 记录以 commit 类型作为开头:
    1. feat 新特性
    2. fix bug 修复
    3. hotfix 对生产代码的紧急修复
    4. docs 文档改动
    5. style 格式化
    6. refactor 重构代码
    7. test 项目测试
  2. commit 的粒度是一个小功能点或一个 bugfix,将恢复的误伤操作降到最低
  3. commit 记录中,用一句简练的话概括,然后空一行阐述提交增加或修改的地方
  4. commit 要有独立性,如果是多个功能相同或相近的 commit 可以使用 rebase -i 合并或调整;如果是对上一个 commit 的修正可以用 amend 修复;禁止无意义的 commit
  5. 如果有临时但暂时不需要提交的改动,可以用 stash 暂存代码
  6. 在有多个 commit,功能开发到达一个里程碑节点或是完成功能再 push,以整洁 origin/master,尽可能一个 push 就是一个 feat
1
2
3
4
5
    feat: 完成用户注册接口

    UserController 添加了用户注册接口 /user/register
    UserService 用户注册接口 userRegister(UserVO),用户密码提供了彩虹表校验
    UserMapper  userRegister(UserPO)

7.2 开发规则

我们需要一个干净整洁的 work tree

  1. 所有的项目开发都会在 dev 分支上进行,生产代码会保留在 master 分支上,非 hotfix 等紧急情况禁止向 master 分支提交
  2. 所有新 feature 的开发都需要建立一个新的、以该 feature 命名的分支,然后在该分支上进行提交后,将其 merge 到 dev 分支上
  3. 项目更新一律使用 rebase,即 git pull --rebase

7.3 其余规范

  1. 谁提交了.idea 或者.vscode 文件夹,谁请喝奶茶