软件工程课程,24个人合作开发一个网站,虽然功能并不是特别的复杂,但是,多人的开发,增添了许多奇奇怪怪的问题,不管怎么说,这门课算是相对圆满的结束了,而作为这24人组织领导者的我也从其中学到了一些项目管理的经验,记下,一来可以回忆,二来可用于今后参考。
开始一个项目
其实,所谓的分模块各自独立开发,完全分离是不可能的。每个人都build from scratch,最后肯定是各自有各自奇怪的接口、结构等等。
所以,要做的第一件事,正确的事,就是建立一个repo,写清楚开发指导,让大家知道如何开始写,这一部分,需要注意,或者说必须要做到的几点:
1. 一个工程
说起来是一句废话,既然最终是完成一个项目,当然是在一个工程里边写了。可是我有点太想当然了,于是还是有因为有的模块用了其它的脚手架,有着差异很大的代码结构,导致了整合时花费了些力气的不愉快经历。
如果是最终是一个整体的项目,一定要在一个工程里写,不要想着先各自写自己的子模块,最后写一个顶层的模块将他们捏合在一起,会很痛苦。
当然,比如像一个网站采取前后端分离的架构,那么前后端两个工程,这是没有关系的。
2. 模块之间的独立性
所有人在一个工程里开发,如果不能有很好的独立性,每个人的开发或多或少都会受到拘束,这是我们不愿意看到的。所以在本次开发过程中,建立工程的同事,就需要规定好每个模块如何相互独立的开发。
以本次工程为例,初始项目中,为6个模块分别在合适的地方建立6个目录,有一个必要的入口文件。比如:
后端:用了Django,那么urls.py
里写好路由映射,路由到对应目录下的urls.py
即可。
前端:用了React生态,需要处理的事情多一些。首先是前端路由,给每个模块的入口component创建路由;其次还有redux的配置,创建根store,让每个子模块创建自己的store并注册到根store中。
这样,初期的开发,每个人在前端直接进入自己的路由,请求后端也全部请求自己子路由下的内容,可以做到相互独立的开发。
3. 示例参考
成员在开发完项目之后,肯定都对所用到的技术栈,一些best practice有或多或少的理解,但是在项目的开始并不是这样的,有许多成员不了解相关的库,框架,语言等。
此时,光给tutorial,documentation等是不够的,成员去学这些东西刚开始需要一段上手时间,而这并不是一个短期一次性项目高效的做法。最直接的就是,写个参考的示例,让不熟悉的成员能够模仿着去写,这样在模仿中学习,能够比较快的掌握所用的知识,同时,也可以学到一些在文档中并不会出现的best practice。
在本次项目的开发中,可以首先写个最简单的前后端交互的示例,有如下的功能:
- 前端发送GET请求
- 后端返回数据,比如Hello World
- 前端redux相关的操作:触发action、reducer的行为、store的改动与视图的更新
- react组件书写的示例
经过以上的几步,基本做好了项目起始的准备,每个人应该知道了在哪里开始写,怎么开始写这最基本的问题。
Git&GitHub使用
本项目的组织方式大致是这样的:
- 所有代码放在一个repo中
- master放整合的代码,受保护
- 每个子模块有自己的分支,该模块的小组成员在此单分支上工作
- 子模块完成某个功能之后,提交PR,将子分支merge到master中
就我个人理解,多人的开发,一般有两种模式,一种是多分支,分支之间PR;另一种是fork-PR。我在这次选择了前者,有几个考虑因素:
- 我可以看到各个子模块的进度,不至于不提交PR我什么都不知道
- 如果必要,我可以直接在某个分支上提交来修改一些代码
- 子模块一个分支上操作足够了,一个子模块有四个人参与,单分支基本满足了要求
单分支多人开发
对于多人在单分支上开发,还是需要遵从一定的workflow才能保证不会出现一些不愉快的事情。比如现在多人开发的单分支为common,可以遵从一下的流程:
git checkout -b local
建立自己的本地分支- coding..coding..
git commit -a -m 'blabla'
在自己的分支上提交git checkout common
切换到common分支git pull
看看别人在这段时间有没有提交git checkout local
git merge common
在自己的分支上merge别人的提交,如果有冲突,解决git checkout common
git merge local
此时,merge 自己分支上的东西,是不会发生冲突的git push
git checkout local
切回自己的分支,保持idle状态在自己本地分支这个习惯
Pull Request的使用
第一次使用Pull Request这个功能,有一些经验不足,导致自己的使用并不是很愉快。
Review这个设计方式很好,在接受更改的时候,可以审核代码,防止不合理的代码污染共有的分支。以下是自己经过尝试之后的一些心得:
- 提交PR之后,只是声明了一个分支到另一个分支的合并,并不是当前提交的状态到另一个分支的合并,所以,提交PR之后的commit,仍然会更新。所以,request change的时候,直接修改就好,不用关掉这个PR再开一个新的PR。
- 提交PR的频率尽可能高,不要憋着一个很大的功能再提交,我的建议是,只要写完了一小块内容,而这块内容不至于编译不通过,运行不起来,就可以提交PR,这样逐渐增加master上的功能,不至于一次提交PR,需要审核好多代码。
blame
之前只是注意到这个按钮,但是并没有细究过它的用处,不过,这次可真的是发现了它的用处哈哈。多人开发里边,真的是神器呀。
blame的功能是可以显示文件中对应行是由谁改动的,并且可以查看历史记录,看起来跟blame没有直接的关系,但其实我用到的时候,恰恰就是blame的时候。
-“这谁把我的代码改掉了???是你吗?”
-“不是我,我怎么可能去动你这部分的代码??”
-“哦,是吗?我们来blame一下”
-“我错了orzorz”
今后多人开发的时候可要善用这个功能。