与一群国外的Dev一起工作是我从未有过的经历,在陌生的国度,陌生的团队,陌生的客户,做着陌生的项目,对我而言,Everything is new。我们在客户这里,仍然采用典型的敏捷方式:故事墙、站会、用户故事、结对编程、持续集成、TDD甚至BDD……几乎所有的敏捷实践我们都会运用。在加入这个项目时,已经进行到第7个迭代,整个项目的框架已经比较成熟。我们的任务是尽快熟悉业务和整个技术框架,并为新的项目做好充分准备。在接近3周的时间内,我们都会和客户以及美国Thoughtworks的同事们进行Pair,通过实际的开发来熟悉和了解业务与技术。然后,在剩下的两周内为新项目做Inception。
项目是基于.NET Framework 4.0进行开发的,采用的技术包括C#, VB.NET, Ext Js, SQL Server 2008。IoC容器为Structure Map,NUnit作为单元测试框架,Moq作为Mock测试框架。我们使用了Jenkins(即Hudson)作为持续集成工具,使用了Thoughtworks的产品Twist作为回归测试和集成测试工具,并使用了Powershell作为构建脚本,Git作为源代码控制工具。
来到LA的第一周。除了第一天参加了几次Meeting,了解了整个项目的情况尤其是业务逻辑之外,第二天就迅速进入团队,开始结对编程。整个第一周,我完成了2个Bug Fix,同时,对Regression Test出现的问题进行了修复,并参与了一个Story的开发。在这一周,我并没有Switch Pair,一直是和客户这边的一位Dev(名叫Andrew)进行合作。
回顾这一周的工作,我的感受如下:
1)业务逻辑的了解比技术更重要
作为一名Dev,可能首先会想到项目会使用什么技术,我对这些技术了解吗?总之,会首先关注一切与技术有关的东西。在进入项目之前,我特别关注了这些内容,并抓紧一切时间为这些技术做储备。当然,我们也希望了解业务逻辑,但由于前期准备时缺乏这方面的条件,我们所能了解的就是项目与Healthcare有关,项目内容有些接近CMS。然而,到了项目之后,我们才发现,技术并非决定你能否快速进入团队,并开始开发和实现的关键。如果不了解业务逻辑,不明确领域术语,我们将很难进行沟通和交流。尤其对于现在这个项目,由于项目已经做了一部分。对领域的了解就更加重要了。对于一名有着多年经验的Dev来讲,其实技术并不会成为制约你进行项目开发的主要瓶颈。在这个项目中,有很多技术都不是我掌握的,但我们仍然可以快速进入开发活动。这是因为Pair Programming可以很好地完成知识共享和传递,我的Pair可以像Mentor一样来带领我迅速进入状态。
2)交流是项目开发的根本
在国内做项目,交流或许也会成为障碍,但因为语言相同的缘故,我们往往将交流活动忽略了,似乎觉得这是顺乎自然的事情。在这一周的工作中,我仿佛进入了另一个世界,耳边充斥地都是自己难以理解的语言。虽然我有一定的英语基础,但真正和这些母语为英语的Dev合作时,才发现我所掌握的英语单词和语法都变得不够用了。我的舌头似乎也打结了,我很难理解Pair所要表达的意思,自己也很难向Pair表达我的意见。这就导致开发效率受到很大影响。即使任务已经完成,整个实现对我而言,仍然似是而非,还需要自己下来看Story的描述,看源代码。例如,在我们项目中已经实现了比较好的Validation机制,但为了实现一个相对较小的Story,由于交流的问题,我们的实现被严重阻碍了。
此外,在我们项目中完全具备现场客户的条件,因而交流更是成为重中之重。我们的BA团队既有TW的,也有客户的。他们都写了很不错的User Story。在我们实现这些User Story时,如有不明白之处,都需要尽快咨询BA,通过交流消除歧义。而在实现之后,必须和BA做Show Case,以尽快获得反馈。这一点非常重要,也是敏捷的核心价值观体现。
3)好的习惯很重要
第一周,和我Pair的Andrew是来自客户的一位实习生。他刚从大学毕业,进入项目大约三个月时间。在大学期间,他只学习了C++,对.NET、Javascript以及CI等内容都不熟悉。换言之,他现在所掌握的所有技术,都是在项目中学到的。虽然是这样一个Intern,但我发现他已经具备了非常良好的编码素质。在开始一个Story时,他会首先在Twist编写Regrssion Test Sceinario。而在实现代码时,也会尝试着通过Unit Test来驱动实现。在提交代码时,会合理地运用Git命令。例如在开发前,会通过Git Status检查当前状态,看是否有变更。在Commit时,如果发现提交的内容有冲突,他会非常慎重地处理Merge。编写代码时,会严格遵循我们制定的编码规范。虽然,他在开发方面的经验还有很多欠缺,但无疑已经有了一个好的开始。我想,通过这个项目的锻炼,在Thoughtworkers的言传身教下,只要他愿意继续努力,应该会有一个很好的发展前景。
同时,对于团队而言,这样良好的编码习惯,就像所谓的“童子军军规”一般影响这团队的每个人,我们欠下的Technical Debt就会少很多,这对于后期的维护、修改以及将来后续的开发,都有非常大的帮助。
4)学会寻求帮助
每个人所掌握的知识总是有限的。或许你的能力足够让你解决任何问题,但考虑成本问题,若能适当地寻求帮助,你既能够快速完成任务,同样能够学到你希望学到的知识。即使寻求帮助后,没有得到你所期望的结果,至少说明,我们可以拒绝某些选项,这同样可以节约时间成本。最关键的一点需要时刻记住,我们是一个Team。
在第一周的Story开发中,由于我和Andrew都对Validation的机制不太熟悉。我们尝试了多种方法,希望解决问题,但都不奏效,这样反复的尝试已经耽搁了大约一天的时间。后来,我们主动找到另一位Thoughtworker-Eric,他已经在项目呆了较长时间。了解我们的问题后,Eric仅用了不到10分钟的时间就解决了这个问题。事实上,这个问题的解决方案需要一个小技巧,在Label中设定我们事先指定的CSSClass,就可以显示那些Validation Message。
5)知识分享
毫无疑问,只有充分的知识分享,才能有效发挥团队的作用。尤其对于新加入团队的成员,如果没有足够好的知识分享,或者团队的老成员不具备这方面的意识,将自己拥有的知识传递给新成员,新成员就很难融入团队,也很难快速地贡献自己的Effort。在知识分享的过程中,通过Meeting和Session,或者阅读文档的方式当然是有效的。但事实上,即使你参加一天的Session,或阅读一天的文档,都不如和你的Pair实际做一个Story,对知识的分享来得更好。根据我自己的经验,所谓Session或文档的方式,更适合介绍一些领域背景知识,或宏观的系统架构。细节知识必须在实践过程中获得。这时,Pair Programming就显得非常重要了。
在选择自己的Pair时,也需要针对实际情况做出调整。例如与新手Pair的必须是相对有经验的Dev(当然也可以和QA或BA结对)。另外,也需要适当地Switch Pair。在这个项目中,我就体会到这一点的重要性。第一周的3天时间,和我Pair的都是Andrew。虽然他已经进入项目三个多月,但毕竟还缺乏一定的经验。而我作为项目新人,更是很多内容都不了解。这样的Pair组合,效果可想而知。在这个过程中,本来我们应该进行Switch,但因为Story的关系,其他Pair也有自己的任务,这个Switch活动就被推迟到了第二周。事实上,在第二周的第一天,我和Eric合作,效果就非常好。整个Velocity得到了较大的提高。