技术研发编码规范
1. 前端规范
2. 后端规范
2.1 API风格 - REST API
在传统的HTTP API风格下,一个用于响应用户列表的API URL通常可能有如下这些命名:
http://www.example.com/view_users
http://www.example.com/user_list
http://www.example.com/all_users
http://www.example.com/user/list
http://www.example.com/user/all
这些URL都可以用来表示响应用户列表,甚至看上去都还是比较规范,因为至少我们能够通过名称直译出API涉及的功能:用户列表。但是我们到底应该选择用哪一种URL作为用户列表的API呢?A程序员可能喜欢用http://www.example.com/view_users ,而B程序员可能又觉得http://www.example.com/user/all更加优雅....当可供选择的方案过多后,往往会造成一种混乱,而这种混乱,对于我们编码来说,就是一种不规范。
为了解决上述的问题, 我们采用REST API风格来尽可能的避免这种混乱!
REST 是 Representational State Transfer(表现层状态转移)的缩写,它是由罗伊·菲尔丁(Roy Fielding)提出的,是用来描述创建 HTTP API 标准的,他发现API中常用的四种行为(查看
view,创建create,编辑edit和删除delete)都可以直接映射到HTTP中已实现的GET,POST,PUT和DELETE方法。
同样对于与 “用户管理” 相关的常见功能,基于REST API风格规范,规范如下:
| HTTP Method | API URL | API功能 | 描述 |
|---|---|---|---|
| GET | /users | 列表 | 获取用户列表 |
| GET | /user/12 | 详细 | 获取id为12的用户详情 |
| POST | /user | 增加 | 新增一个用户 |
| PUT | /user/12 | 修改 | 修改id为12的用户部分信息 |
| DELETE | /user/12 | 删除 | 删除id为12的用户 |
| POST | /user/12 | 详情或新增 | 获取id为12的用户信息,若不存在则添加一个id为12的新用户 |
2.2 项目结构
传统的MVC三层架构已经非常成熟,但当项目过于庞大,业务逻辑趋于复杂的时候,项目代码会变得异常冗杂,这将很容易导致我们在修改一个功能时,面临谁都很难说清模块的具体功能意图是啥的问题,进而往往迭代一个功能时,光是回溯该功能修改点就需要很长的时间;更别提多模块彼此关联的情况下,修改带来的不可预知的影响面。
而另一种已提出多年的DDD领域驱动设计(MVC属于数据库驱动设计),虽然不乏是一种优秀的开发设计思想,但因为其繁琐的新概念和设计理念往往会为开发带来新成本,且一定程度上提高了编码人员的水平要求;而且目前国内关于DDD的最贱实践过少,所以很多情况下DDD难以落地。
DDD把领域模型的重要性提高到了数据模型之上,在传统的MVC分层架构下。我们将项目结构分为Controller,Service,DAO 这三个主要的层,所有的业务逻辑都在Service中体现,而我们的实体类Entity却只是充当一个与数据库做ORM映射的数据容器而已,它并没有反映出模型的业务价值。所以又把这种模型称为“贫血模型”。“贫血模型”有什么坏处呢?在我们的代码 中将会到处看到各种的setter方法和各种各样的参数校验的代码,尤其是在Service层,但是这些代码它并没有反映出它的业务价值。这就是事务脚本的架构下,所呈现出来的弊端,这种模式下认为数据模型优先,所以会导致开发人员和产品经理在讨论问题的时候,完全是从两个角度在思考问题。开发人员听到需求后,脑袋里想的并不是如何反应出业务的价值,而是考虑的是数据库表怎么设计,字段该怎么加这些问题。所以DDD中提出了通用语言这么一个概念,并且基本将通用语言的概念贯穿于整个落地的过程。这样会大大的减少成员之间的沟通成本(前提是大家都从心里接受了DDD)。
为什么DDD难以落地呢?
第一,国内关于DDD的最佳实践还是太少了,除了知名的几个大厂以外很少看到有关于DDD的落地实践。这里附上美团的DDD实践,美团领域驱动设计;最佳实践太少意味着,我们可以参考的资料就少,承担的项目失败的风险就大。
第二,DDD中出现了很多的概念和术语,比如 聚合根,值对象,六边形架构,CQRS(命令和查询职责分离),事件驱动等等概念。很多人看到了这么多概念的时候,心中就开始打退堂鼓了。
第三,DDD需要我们在领域建模花费很多的时间和精力,而且还可能导致付出和收益不成正比的情况。因为在界限上下文的划分上是非常考验架构师的业务水平。如果没有将业务模型很好的识别出来,那么可能很快模型就会在迭代的过程中腐败掉了。
固我们基于两种设计模式的特点,采取了一种折中的思想,在参考部分优秀GO开源项目的情况下,优化解决了MVC和DDD这两种模式下各自的一些传统弊端,提供了两套项目目录结构和对应的示例项目。并且规范如下:
| 项目规模 | 项目结构 | 模板项目仓库 |
|---|---|---|
| 中小型项目 | MVC | github.com/whereabouts… |
| 中大型项目 | DDD | github.com/whereabouts… |
注:项目落点前需充分评审和分析,以此定义项目规模和选取项目结构。
2.2.1 MVC
开发制定中...
2.2.2 DDD
开发制定中...
2.3 数据库规范
- 批量操作不允许使用事务;
事务若失败则大量数据回滚,反复读写,IO负载过大容易导致mongo崩溃;推荐使用事务的场景:多表同步更新,且更新数据量小时。
- 业务代码中不允许操作索引,由运维统一管理;
- 代码中的查询必须命中索引,禁止全表扫描;
- mongodb加索引必须配置
background,应在后台执行; - Redis/Tendis禁止使用
keys *操作; - 数据库连接必须使用连接池,连接使用完毕后必须释放;
2.4 Git代码管理规范
- master分支禁止做
push操作 - 解决冲突必须和冲突方确认