ThoughtWorks University 取经第二记
接续上一篇文章关于ThoughtWorks 公司文化和敏捷开发思想的传承,这篇文章主要描述的是我在ThoughtWorks University所接受的敏捷开发技术培训的内容和方式,在一些介绍中会穿插一些对我的真实工作所起到的影响。下面就请跟我一起走入TWU的课堂。
ThoughtWorks对于技术培训的方式很特别,总体感觉是更频繁的获得反馈保证更高效的沟通。其中值得一提的是每周一进行的“期望与担忧”和每早的“站立会议。“期望与担忧”进行方式很有趣,每周一一到你会发现老师在墙上挂了一张大白纸上面写着一周我们将要学习的课程,每个课程下面都有耐人寻味的留白。从老师简短的介绍里得知,他是想通过这个环节与学生进行第一轮的互动。我们用颜色不同的贴纸用以表示不同的寓意,正如照片所展示的,所有学员会用十五分钟的时间,审查每一个课程的名称,然后在红色的(代表担忧)或者绿色的(代表期待)贴纸写上内容,并贴在相应的课程下面。例如,所有学员对于叫做“编程中所用到的设计模式”的课程就会有“什么叫设计模式?”,“我怕我无法辨别什么时候使用设计模式”等各方面的担心,而也会有“我想上课的过程中编程体验一下设计模式的应用”,“我要学Strategy 模式”等方面的期待。而每堂课结束的最后几分钟,老师们会审查这些期望与担忧,看看自己所讲得内容是不是覆盖到了各个部分。这个流程所起到的效果就是让学员们有针对性的去上课,在上课前就思考一下自己想获得什么,都会有哪些困难从而达到了良好吸收知识的效果。每天早上的“站立会议”也很有意思,之所以叫站立会议是因为大家开会的时候都站着,这样大家就会集中精力,好好利用每一秒钟的时间,以便不用站得太久累到自己。在站立会议的时候,我们会站成一个大圈让彼此能够正面相对,为了避免大家争抢说话,每个人要说话的时候都要拿一个标志(学员们用的是我们自己命名的俄罗斯吉祥物──小象Gima)。站立会议的基本内容是你昨天都学了(或做了)什么,今天打算干些什么,以及老师从“垃圾袋”中翻出的另学员“谈之变色”的回顾问题(其实回答不出来只不过吐吐舌头罢了),比起这些我个人认为最重要的是站立会议是一个信息共享的渠道,这个时候是最好的分享经验心得和寻求帮助的时候,这种有效沟通的方式可以让你一天的工作效率大大提升。好了,下面就该进入真正的主题了,看看ThoughtWorks是怎么进行软件开发技术的培训了。
老师给我们准备了,TDD(Test Driven Development测试驱动开发)、结对开发、面向对象编程、测试与Mock、重构、自动化测试、持续集成等课程大餐。通过学习这些知识和技术,使所有学员可谓真真正正窥见了软件开发的流程,为以后在工作中大战拳脚打下了扎实的基础。即使是针对这些具体的技术培训,与国内大学所使用的以讲为主的授课方式完全相反,ThoughtWorks 采用让学员主动参与,随时提问,动手实践,及时总结等方式,争取让每次课程的内容被消化在课堂上。我们培训的地点就是公司租用旁边一家五星级酒店的会议厅,整个大厅非常宽敞,学员们可以随时更换自己的位置,老师们平时使用投影仪和白板进行授课,如果需要他们会坐在学员旁边亲手指导,学员在实践过程中有了问题,也可以立即跑到老师跟前询问解决方案,这样的环境非常便于学员之间、学员与老师之间的交流。例如在培训测试驱动开发的时候,老师并没有立即告诉我们什么是测试驱动开发,而是让我们分成四个小组自己讨论二十分钟,每个小组在大厅的一面拥有一个白板,讨论结束后每个小组选派一个代表,根据白板上的记录向所有学员和老师介绍你们小组理念中的测试驱动开发是什么,如下面的照片所展示,Kunal正在向全体同学介绍他们小组的观点,而所有其他的学员随时可以提出质疑,老师也可以纠正一些错误的观点。经过小组讨论的环节后,老师会对大家所阐述的各种观点进行查漏补缺和总结,通常总结的行为方式也是多种多样的,有可能直接用大白纸写出来然后贴在墙上,也有可能用思维图的方式画在白板上等等,这些方式都增强了我们收集内容的可视性也使讨论过程更高效。最后,老师再现了一个用测试驱动开发的完整实例,反复的强掉了测试驱动开发中设计大于测试的理念──即用测试书写你的思想,用代码实现该思想,而不仅仅只是一种测试开发方法的原理 。这种让学员积极参与和进行演讲的教学方式,使得所有人对教学的内容都有了自己的理解,并深深地印在了脑海中。
其实对于ThoughtWorks,结对并不仅仅是应用在编程中,我们几乎做什么事情都结对,老师们结对讲课,学员们结对演讲,结对研究新技术,结对做课后作业,当然还有著名的结对编程了。结对的方式促使我们更频繁的沟通,更高效的知识分享,这也是为什么我在上文中使用了结对开发而不是结对编程这个词的原因了。很有趣的事情是,老师们在上课时给我们传授结对思想的时候,让我们讨论的主题是结对的好处和坏处。当被问到结对有什么坏处的时候,学员们怎么想都想不出来,没想到身为资深开发者的老师Khali大声地说到:“结对编程非常的累,因为你总是全神贯注,而且总是有人盯着你,你必须工作呀。每天结对完之后,我都累得不想动了,当然结对的时候还是很有趣的。”对于这样的诚恳的答案所有的学员都爽朗的笑了起来。回国后在ThoughtWorks项目管理产品Mingle团队的实际工作,让我体验到了结对的种种好处,业务分析员结对给我介绍软件的各种功能,让我很快的了解到我们要做什么。资深的开发者跟我结对编程,保证项目进度的同时,也教给我许多编写代码的知识和技巧,更值得一提的是让我学会了他们遇到问题的思维方式和解决问题的处理方法,这如果靠一个人独自摸索,真的不知道要花多长时间。直到工作几个月后,才真正理解到结对给团队带来的巨大好处,当然每天也的确很累。
面向对象编程、测试与Mock、重构都是敏捷开发方法中所涉及的具体内容。ThoughtWorks University的老师通过两个小故事的开发让我们真的体会到了为什么以及什么时候使用与之对应的技术。老师们用一个关于飞机场的开发素材让我们了解到面向对象编程中良好的封装性、单一职责原则、Liskov 替换原则(LSP)、递归算法、Strategy设计模式等开发知识。另外一个关于停车场的开发故事,让我们了解到了Mock对象在测试中的使用、重构的必要性和艺术、Composite设计模式等知识点。拿飞机场故事为例,老师们在课堂开始的时候会给我们描述完整故事的一个小部分,然后每次给每个结对(Pair)十分钟的理解需求和发问时间,五分钟的设计时间,十五分钟的开发时间;在开发的过程中要灵活的使用测试驱动开发、结对编程和重构的各个技巧;在每个开发周期之后,如果没有任何一个结对完成了功能,则进行下一个十五分钟的开发周期,否则就会请一个结对上台展示他们的代码,在展示的过程中首先运行测试保证功能全部完成,然后由该结对的成员讲述他们的实现思路和具体方法,可以随时发问和提出更好的方案,最后老师会进行总结并展示自己编写的代码以供大家仔细分析。还有一点在培训开发方法的时候非常值得注意,其实对ThoughtWorks有过接触的朋友通常对ThoughtWorks的开发人员有一点印象非常深刻,就是他们是一群使用开发工具尤为流畅的群体,他们不但可以熟练的运用各种开发工具,更能够飞快的使用工具的快捷键进行代码的编写。其实我们在实现这些开发素材的时候,老师专门给我们培训过相关工具的快捷键,并且把最常见的快捷键书写在大白纸挂在我们的头顶,我们只要抬头便看得见,真正在开发的过程中我们也会很努力的使用这些快捷键,很快得就可以灵活运用了。使用快捷键可以极大的提高开发速度,而且它更有助于开发者保持开发思路,如果你使用快捷键非常熟练,往往在开发的过程中,不需要思考就可以实现几个视图、类的切换,否则使用鼠标时为了寻找按钮的那段停顿期,往往会让你的思路受到干扰,这也可能是为什么那么多ThoughtWorker为快捷键乐此不疲的原因之一吧。
自动化测试、持续集成是敏捷开发技术中的重中之重。在ThoughtWorks University的培训课程中我们会学习,利用JUnit编写单元测试,利用Selenium进行功能性测试,利用Ant编写运行自动化测试的脚本,利用Subversion进行代码的持续集成, 使用Cruise(或Cruise Control)作为自动化构建的工具等课程。老师给我们传授这些知识的的最佳方法也就是让我们实际在开发过程中演练这些技术和工具。其实这些课程展现了在ThoughtWorks的真实工作流程:我们在测试驱动开发的过程中通常会使用测试框架(JUnit)先编写测试,在开发完一个简单的功能后,会运行测试脚本(Ant),在本地运行所有的测试以确保编写的代码没有对别的功能有所破坏;然后 会用版本控制工具(Subversion)将代码提交到代码库中;代码库中还包括测试人员编写的Selenium测试脚本;这时自动化构建工具(Cruise)就会开始自动运行所有的测试,如果失败会给团队亮出红灯,表示软件处于不可用的状态,这时团队的成员就会集中精力来解决错误,自动构建工具还可以自动生成可运行的软件以供客户试用。总之,代码库中的软件始终要处于可运行的状态,这在某种程度上也保证了用户可以直接试用软件,从而提出有价值的回馈信息。在 ThoughtWorks中国分公司有很多关于持续集成的小故事,其中最有趣的是同事李晓告诉我的关于一个下午听那首经典的“Only You”的故事:李晓根据构建的情况开发出了一个构建结果自动提醒的语音程序,如果构建失败就会播放指定的歌曲和最后提交代码的开发者的名字,有一次某人提交了一段代码使构建失败了,结果始终找不到错误的来源地,整整一个下午办公室都激荡着这首著名的歌曲和某人的大名,据他所说那个时候该团队空前的一致集中精力找错误。在ThoughtWorks中跟这些很有创意的同事们一起工作,总是会有新的惊喜和收获。
最后的测试──项目评估
前五周的知识积累,使所有学员都迫不及待的希望在某个项目上灵活运用一下,这就是最后一周的实战内容──一个公司内部使用的项目,这个项目完全由学员自行开发,老师们扮演客户的角色,开发结束后会直接供公司内部使用或者由别的团队接管继续开发。在紧张的一周开发过程中,所有学员每天九点到下午三点是实际的开发过程,下午三点到五点是向客户展示,询问意见,以及对当天团队情况进行总结和信息回馈的过程。每天学员中都会有人扮演 IM(Iteration Manager)负责管理开发的具体事宜,首席BA(Business Analyst业务分析员)负责所有BA事宜的决断,首席DEV(开发人员)管理开发团队,首席QA(测试人员)调空测试人员的任务。各个不同的领导者角色每天都会在不同的学员中进行轮换,以满足绝大多数愿意尝试管理角色的学员都有机会尝试。整整一周的评估,真正地体验了什么叫“魔鬼客户”的难缠程度,也许老师们的目的就是让我们体验一下大强度、高压力、多任务的工作环境。第一天,意料中的混乱,有人把未经测试的代码提交到代码库中去了,所以构建库对我们展示了一整天晚霞般红通通的笑脸,在当天的展示阶段,我们战战兢兢的向脸上阴云密布的客户展示了惟一一个能拿得出手的开发功能。不过当天之后的总结和信息反馈阶段,学员们一起努力提出了很多有效地解决方案,之后的每一天都会有很大的改观,最后我们成功的提交了七个完全复合客户需求的功能,老师们对我们的表现也非常的满意。终于,我们成功的毕业了!!!
总结
其实还有许多有趣的故事还记忆犹新,比如为了驱散每日中午的困顿,大家会把各个国家的游戏集合起来,每天中午都一起玩一个,我们称这种活动为“振奋精神”;每天下课后都会有学员自己主持的技术介绍演讲,学员可自愿参加,切身体会一下当前又新又优秀的各种技术,从而更好地面对自己即将到来的工作。就这样思维活跃的人走在了一起,迎面遇到的每一个困难都去努力解决,大家团结在一起体验了一次软件开发的盛宴,最后告别终究还是会来临,不过美好的记忆和所学的知识却永远的伴随左右。仅以此文献给我ThoughtWorks University的各位好友,同时也希望本文对各位读者能有所启迪。