tinyTikTok 规范设计|青训营笔记

171 阅读6分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 30 天

本篇文章归档于 “第五届字节跳动青训营”,主要是为了完成和记录掘金的 “伴学笔记创作活动” 活动,如果你对我的其他文章感兴趣,可以去我的 专栏 中逛逛看有没有你想要的东西。

放在前面的话

谈到开源项目,大部分 coder 往往更在意它的代码结构、代码质量以及代码测试,但对于一个合格的开源项目,社区也是不可或缺的一部分,最直观的来说,便是文档健全和日志信息。

之于一个优秀的开源项目,我认为它应该社区氛围 >= 代码质量,开源的意义不仅仅是分享,更是为了帮助项目成长,提高认可度,同时,也在成就参与者。

因此,我将谈到的设计规范不会仅限于代码规范。

commit 规范

commit 内容是一个老生常谈的问题,通常情况下,遵循 Angular JS 的文档是准没错的,对于不同的项目,可能会有特别的规范,我这里便以 tinyTikTok 的为例:

类型说明
feat添加新功能
fix修复 bug
docs文档类更新
refactor重构代码
test测试类代码的更新
chore其他类型

因为 tinyTikTok 毕竟是一个 toy program,所以仅规范这几种类型即可。

关于 commit 的具体内容,通常情况下使用 -m 简明阐述更改内容即可,如果有一些不兼容更改,则应使用 -a,并以 BREAK CHANGE 开头,解释具体的更改。

当然,如果是修复了某个 Issue,还可以添加一行 Fixed #<issue number> 作为 footer。

除此之外,对于 commit 的内容,还应该学会使用 rebase 合并相似 commit。

版本号规范

去年面试 VMware 时有提到过版本号的规范问题,这里做一个简单的总结:

  • 版本号的模版:v<主版本号>.<次版本号>.<修订号>-<先行版本号>+<编译版本号>(先行版本及编译版本并不是稳定版本);
  • 标记版本号的软件发行后,禁止改变该版本软件的内容,任何修改都必须以新版本发行;
  • 修订号必须在只做了向下兼容的修正时才递增,其实就是 Bug 修复。
  • 次版本号必须在有向下兼容的新功能出现时递增,在任何公共 API 的功能被标记为弃用时也必须递增,当有改进时也可以递增,每当次版本号递增时,修订号必须归零;
  • 主版本号必须在有任何不兼容的修改被加入公共 API 时递增,每当主版本号递增时,次版本号和修订号必须归零。(主版本号为 0 的软件处于开发初始阶段,一切都可能随时被改变,这样的公共 API 不应该被视为稳定版)

实际上,在开发过程中,你可以理解为:

  • fix 类型的 commit 可以将修订好 +1;
  • feat 类型的 commit 可以将次版本号 +1;
  • 带有 BREAKING CHANGE 的 commit 可以将主版本号 +1。

目录结构规范

跳过确定需求等流程,如何起项目也是值得讨论的,优秀的项目结构应该是:命名清晰、功能明确、全面、可观测和可扩展的。常见的组织方式有两种:平铺式和结构式。

平铺式的组织方式可以直接参考一下字节的自研基础网络库 netpoll,对于不复杂的项目,可以一目了然,但通常情况下,推荐使用结构式组织项目,这里也以 tinyTikTok 为例:

.
├── CHANGELOG
├── LICENSE
├── Makefile
├── README.md
├── README.zh.md
├── api
├── build
├── cmd
├── docs
├── internal
│   └── pkg
├── pkg
├── scripts
│   └── make-rules
├── simple-demo
└── test

特别地,放到前面解释一下:

  • simple-demo:中的内容其实就是原 simple-demo 内容;
  • README(.zh).md对于一个开源项目,我认为一份英文版本的 README 是必要的,但 tinyTikTok 受众是国内 coder,所以还应该准备一份 .zh 版本以方便阅读。

其他部分几乎可以套用:

  • CHANGELOG:字面意思,用来记录修改日志的;
  • LICENSE:可以按严格程度粗略排序:GPL > MPL > LGPL > Apache > BSD > MIT。更多内容出门右转 Google;
  • Makefile:利用 make 来进行项目管理;
  • api:存放对外提供的各种不同类型的 API 接口定义文件,如 swagger;
  • build:存放安装包和持续集成相关的文件;
  • cmd:存放所有组件的 main 函数;
  • docs:存放文档;
  • internal:存放该项目内部使用的代码,所有的代码可以一开始无脑存 internal/pkg,等重构时再设计具体的结构;
  • pkg:存放可以被外部使用的代码;
  • scripts:存放脚本代码
  • test:存放测试代码。

工作流规范

对于单人开发,几乎都是以快为准,因为不用考虑冲突的问题,而对于多人开发,则会复杂一些,再加上 private 的仓库不允许 fork,所有人都对一个仓库进行操作,所以应该对分支进行规范。

这里可以参考一下 commit 的命名规范,但有一个细节应当注意,分支改动不宜太大,不然 Review 代码时会大大加重 Reviewer 的负担(这是我在参与 ShardingSphere 建设过程后的体会),更加推荐“小改动,多 PR”的形式。

Go 规范

这里的东西就太多了,先给一个参考文档 Uber Go Style Guide,这也几乎是业界标准了。除此之外,还应该保证单测覆盖率在 80% 以上等等。

当然,如果还能根据理解合理应用一些设计模式则是最好不过。

文档规范

除了已有的 README,还应该包含项目文档,如开发文档和用户文档,以及 API 文档(可以用 swagger 去生成)等相关文档。

放到最后的话

从一个好应用进化成一个好项目是非常复杂,事先约定好规范可以在很多细节上达成一致,也可以省去很多后顾之忧。