《敏捷软件开发宣言》
我们一直在实践中探寻更好的软件开发方法,身体力行的同时也帮助他人。由此我们建立了如下价值观:
个体和互动 高于 流程和工具
工作的软件 高于 详尽的文档
客户合作 高于 合同谈判
响应变化 高于 遵循计划
也就是说,尽管右项有其价值,我们更重视左项的价值。
小而精的团队,往往更具有战斗力。我们提倡敏捷,也愿意相信它的价值,然而敏捷的实践却不仅仅是清晨站会、打打估算扑克那么简单。在我看来,其中最容易被忽视的一句便是:尽管右项有其价值,我们更重视左项的价值。如果一个开发者不写文档的理由是“我敏捷”,这就大错特错了,我所理解的敏捷,是关于『沟通』和『协作』的方式。
沟通自然重要,信息在传递中存在损失的可能,所以提倡尽可能的与客户直接沟通获取一手信息,避免经手N个人才到最终的实施者。同样的,部分信息也需要共享给团队成员或者stakeholder,由于沟通存在成本,所以方式方法亦很重要。
团队也需要协作,看板驱动带来潜在的负面影响就是每个人只关注用例,对项目整体的看法缺失,成员间的协作变少,由此在整个项目上出现了不同的视角。短期内任务是完成了,长远看分裂会逐渐积累。
敏捷是关于一个团队整体的态度,那么什么样的态度对团队是有益的呢?我们不妨审视一下以Github为代表的开源开发方式,并引入多种可用的工具,看能不能从中受到一些启发。
信息的有效推送与管理
程序员不喜欢邮件,认为邮件是浪费生命。无缘无故的被加入到邮件列表中,看着大家开始扯皮,扯到最后发现和自己没有一分钱关系,尴尬的是不看又不确定和自己有没有关系。又或者突然转发给自己了一封邮件,打开里面长长的对话,读了很久才知道说了什么。
这里的问题在于,邮件并不适合归档和提取信息,并且是强干扰因素。不妨回想一下,有没有参与这样一种项目,就是全程没有文档,进入项目组的当天转给你N封邮件让你读?再或者,连看板工具也没有,大家通过一个excel文件,标成黄色背景的你做,标成绿色背景的我做,彼此通过邮件来发送这个excel文件?
换一种思路,如果没有邮件,我们如何沟通?
Github有个非常好用的工具:Issues,任何人有问题、建议、计划等都会在里面建条目,然后完善Issue的详情并且展开讨论。上千人协作的项目用它用的不亦乐乎,这里的关键在于,信息完全是公开的,任何人都可以讨论,每个人只在必要的时候介入。同时,信息的噪音也很小。
这也是为什么Github被称为社交化编程。形象的打个比方,邮件好比写博客打架,你写一篇我写一篇,观点被不断放大,而Issue为基础的工作流则更像是Twitter,我说『filtering()方法出错了,报null异常』,下面有人回复『L30的null检查没有做,@Javis 请看一下』。
接下来,对PM来说,看来这个优先级比较高,马上打了个critical的标签,然后放在了current-milestone并分配给了@Javis,即刻,@Javis的上桌面上收到了通知,1分钟改好后提交了。
由于故事本身被限制在了一个很小的Item中,每个人可以更加关注于其本身。如果需要引入类似看板的功能,推荐大家试用ZenHub扩展。
另外,诸如Teambition, Tower, Trello这样的工具也可以提供灵活的任务管理,将一个大的用例切成小的部分,针对每个部分单独讨论,可以降低沟通成本,并且为归档提供了更多参考,不过,这些工具更倾向于客户与开发团队间针对需求和进度的沟通。
如果只是开发团队内的沟通,Github Issues, Jira, Redmine这些耳熟能详的缺陷跟踪工具一定可以帮助团队,让信息更加的透明,尽可能的减少信息干扰,降低沟通的成本
知识传递——通过工具写文档,随时共享你的想法
任务管理,或者缺陷跟踪的本质,是为了让信息便于管理和推送,同时带来一个新的挑战就是信息的归档。有很多的任务,其下对应的讨论是很有价值的,如果整个Item都是有限定的在讨论,那么从中提取信息就会变得容易。更进一步,可以将用例的讨论变成使用手册吗?可以将针对某个具体技术点的讨论变成团队共享的知识库吗?
知识库是全团队受益的,虽然敏捷认为文档的优先级不是最高的,但是绝不是说它不重要。对于程序员来说,有时候并不是不愿意写文档,而是写文档的工具不好用。
从Github得到的安利,就是好用的wikis工具,你值得拥有。结构化的文档体系,不需要安装任何软件就能写,每个人都能编辑完善,告别word和excel。
PM和开发人员应该对产生的Issues(或者叫Task)保持敏感,随时准备好提取和分享这些知识。而Email驱动的工作流养成的坏习惯,就是当需要将一些信息提供给他人时,不做任何修饰的把邮件列表转发出去。
当引入Issues(Task)驱动的工作流时,在它结束或close的时候,是最好的审视时机,回顾一遍,看有没有什么能共享的可以尝试归纳整理,分享是会上瘾的。
这件事,还有个非常著名的名词,叫做『知识传递』。
怕花钱?怕信息泄露?不妨试试Gollum(Github的wikis也是用它),其它的任务管理、缺陷管理工具也大部分也都提供wikis工具(例如Redmine, Jira),一朝架设,终身受益啊。
非正式的沟通
有时候面对面的沟通,或者电话会议是无法避免的。任务管理工具也有自身的短板,就是不适合讨论非常复杂的问题。
Skype在语音方面的表现相当的好而且免费,但是作为一个消息工具,它的确显得不怎么好用,或许在与客户沟通时使用Skype已经足够了,但是对程序员来说,频繁的分享代码片断,或者在群聊中@某个人时,它的表现并不抢眼,想加粗某段话都不支持。
QQ,微信,更不用说,只聊天还行,协作并不是他们所擅长的。
程序员需要更好的交流工具,尤其是文字的。如果已经使用了Github Issues,就会发现,@某个人,或者链接某段代码非常方便,再者,贴出的代码带有语法高亮让人看着非常舒服,毕竟,程序员之间经常说“黑话”,一段没有高亮并且不是等宽字体的代码非常跌份儿。诚然,Issues作为非正式的沟通工具还是显得太不正式了……
不如,试试火爆全球的Slack?基于轻量级的Channel(可以想像成一个随意进出的微信群)可以快速拉几个人进行讨论某个Subject,丰富的ref功能可以随意的@人和链接一切,尤为重要的,就是它支持Markdown,而且它足够的轻量,相信试用一下就会爱上它的。
这并不是故事的全部,最有杀伤力的一点,它可以集成进任何的系统,持续集成、持续部署、运维监测、自动化机器人,比如@WallE deploy production,就会触发部署消息传递到你的运维系统开始部署,试试吧。
当然了,国外有的中国就早晚会有,就像twitter和微博……国内的『简聊』(Teambition团队做的)做的也非常不错,功能类似,推荐一试。
善用VCS工具
Github带来的另一个启迪,就是关于源代码管理的方式。众多的VCS工具,从TFS到svn,从Mercurial到git,无疑给了我们太多的选择,用好哪一个都会带来极大的生产力提高,然而事实并不如此。
很多的团队,仍认为VCS就是个存代码的地方,这或多或少的会给流程带来一定的影响。Github提供的思路很独特,在git的基础上创新的提供了pull request工作流。我们都确信code review带来的价值,我们也认同unit testing为QA带来的红利,但事实上做的人很少,有流程和其它的原因,当然也有工具不够好用的原因。
而pull request这种方式为我们提供了一种思路。善用工具,就得理解工具背后的文化,比如从svn迁移到git,就不应该在同一个分支上死签入到底了。从任务管理或缺陷管理工具开始一个新的任务,马上新开一个分支,不断的提交与实现,当完成时发起pull request让团队内的其它人来review是一种很好的知识传递的方式,同时,在pull request的窗口期内也可以不断的改善,确保最终的合并是一种完整的合并,这种一致化的体验在其它的VCS系统中是很难做到的。
相信工具的力量,架个git试试吧,别用svn了,比如试试Gitlab, Gogs,或者用在线的coding.net、码云、Bitbucket,都是免费的而且提供私有托管,不费事儿。
真实案例
过去的一段时间,我有幸见证并参与改善了一个团队(以下称A)从土作坊开发到敏捷主动改变的过程,权当是一种茶余饭后的消遣吧,并为大家进行敏捷导入提供一种基于工具的思路。
A开发团队差不多20人左右,移动端、前端、后端、运维,开始的时候并没有很严格的流程一说,用的是TFS来管理所有代码(所幸用的是TFS git),前端没有仓库,手机端两个仓库,后端5到8个仓库分别对应不同的服务,沟通用QQ,但是与产品团队一起使用Worktile(类似Teambition)。
初期的流程是这样的,产品团队预先一两周给出需要开发的任务,开发的任务会在Worktile上拆成单个最小需求,后端团队开始将任务分配到人(整体任务),并且是责任制度,谁负责哪个模块就分那个模块相关的任务,开发团队在一周内给出所有移动端和前端需要的接口定义,移动端紧接着开始开发。运维团队有自研的发布系统但几近瘫痪,因为大家都愿意用手动build去服务器覆盖的方式部署,并且通讯工具只有QQ。
进入团队后的第一件事,就是架设gitlab,将全线的产品从TFS迁移到gitlab,为什么呢?因为gitlab的工具生态系统很完善了,并且……免费。
之后,开始改善团队流程,引入每日站会,并严格按照敏捷站会发言不打断的原则执行,为什么呢?先培养习惯。几周后,从最初开始大家反映没什么可说,别人说的听不懂(因为只负责自己的部分),到开始限制每人的发言时间,是个极大的转变,团队成员开始对整个项目有了整体的理解了。
接下来解决后端的问题,发现几个仓库间代码重复严重,没有共享组件而是用原始的复制粘贴,于是大约花了近两个月时间,将原有的后端仓库拆分成十五个左右的独立子仓库,每个仓库安全按照Githab开源软件的方式管理,有问题或缺陷直接去仓库提Issue,也可以跨“职责”提交pull request,并将前端部分从后端仓库中拆出去独立管理和发布。
氛围变的明朗了许多,并且在本来时间就很紧的进度下,每周集体抽出一到两个小时分享自己“负责”的项目、心得等,虽然刚开始并没有多少人分享,但后来就多了,能明显感受到团队的信心值在增加。每次的分享结束后,我都会将整个分享整理成知识库放在wikis中,后来逐渐的整个团队开始参与,wikis数目上涨非常快。
这些流程在团队内完全理清后,最后一个团队大动作就是每周至少2小时的交叉code review,并不是说这种方式有多好,在进度压力过大的情况下的一种变通吧,有总胜过无,更何况code review还真提供了不少新的思路。
然后就是运维团队,发布时手动去生产环境覆盖这事儿我一直不太能接受,后来和运维的伙伴们一起引入持续集成和持续部署,为此还单独写了一个基于F#的DSL描述库,用来快速配置新服务进行持续集成和发布,最终的效果是所有后端仓库从建Issue到修改完提交,到进行单元测试、打发布包、蓝绿发布(或者发布组件的升级包到内部源),整个过程最快5分钟完成。
后来将整个流程逐渐推广到前端和移动端团队,团队气氛很不错。
到离开A团队时,后端大约有20个子系统以及40多个仓库在分别独立的以开源软件的方式运转,团队成员基本可以在所有子项目间无障碍的交叉提交代码,并且还开源了内部开发的用于Kafka的.NET SDK,上述的工具几乎都在使用。不用PM参与,成员就可以自发的对每个系统提出改善的建议和优化。
一个敏捷理性的团队。
结语
我们讨论一切,最终的目的是想让一个团队,尤其是一个敏捷团队变的理性和主动,要相信工具的力量,并且要变的乐于分享,这些文档、工具、流程不仅可以让团队的生产力更进一层,更重要的是积累下了宝贵的智力资产,这些是省钱省不出来的,也是买不到的。