-
2008-04-25
新项目,新体验
又到周末了,由于CodeJam的原因,这已经是我连续第十二天的工作了,有些许疲惫。在这个即将到来的周末,要好好让自己放松一下。
这周开始了一个新的项目,一个Ruby on Rails的项目,一个让我期盼了很久的项目,也是我之前学习Rails的最重要原因。不过,Rails是我最近的blog中出现频率很高的字眼,所以,我并不打算在这里聊Rails的话题。
既然不谈技术,那就不妨聊一些与自己之前做项目不同的体验吧!
在我们这里开发的准确的说是这个项目的第二阶段,也就是这个项目已经有了很多东西,之前这个项目是由美国那边的团队来做,所以,我得到了一个观察国外的ThoughtWorker如何做事的机会。原来参与过的项目里面,更多的是中国这边的ThoughtWorker,所以,我饶有兴致去观察一下二者之间的差异。由于参与这个项目的ThoughtWorker大多是有经验的开发者,所以,很多方面做得成熟许多。
这个项目的自动化程度很高,显然,这些ThoughtWorker在开发之初做了很多工作,把许多可以自动化处理的部分都放到的Rakefile里面。所以,我们得以把更多的精力放在开发本身上,少了很多繁琐的操作。一个简单的例子是,我们提交代码只要简单敲一个命令,首先会到SVN进行更新,然后重做数据库,运行测试,随后,把增加的部分找出来添加到SVN中,最后,它会问我们Pair的人,Story的编号,以及做了哪些工作,以便生成SVN提交的日志。和大多数自动化的工作一样,这些工作本身没有任何技术难度,但有了这些之后,我们可以少敲一些命令,更关注开发本身。其实,之前的几个项目也有一些自动化,比如用Cruise Control做持续集成,但这个项目应该是我经历过的自动化程度最高的项目,差不多常见的重复性工作都自动化了,看看那长长的Rake任务列表便可见一斑。
每天早上,Standup之后,我们会把所有的Dev召集到一起,一起来看一下昨天的工作。我们用SVN diff把代码的差异列出来,大家一起来过。如果恰好是自己做的代码,编写代码的人就会站出来,为大家简单解释一下做了些什么。这样,这样保证大家都会了解到项目的进展。这样做还有另外一个原因,因为我们是一个分布式团队,除了我们在中国这边,还有几个人在美国开发,这样过代码,便可以大致了解到美国那边在我们睡觉的时候干了些什么。
这个项目还有一个做得我觉得不错的地方,就是Story做得很细致。我们在Mingle里面的Story,很多都会有完成这个Story要做哪些步骤的描述。我们只要按照这些步骤一步步做下去就可以了,每完成一个步骤,就做一个简单的标记,这样,几乎不会有遗漏。除了Mingle上的Story,我们还会有专门的文档对这个Story进行比较详细的解释,包括一些验收条件。显然,这个项目的BA做了大量的工作,让我们后续的开发更容易。
这个项目从美国过来了一个BA和两个Dev,而Pair的过程,让我不得不每一天都以英语进行交流。私下里,我经常说,我的英语水平代表了TW的最低水平。当年面试的时候,我自认为表现的最差的就是结对编程,因为一个英国同事高高兴兴搬了把椅子做在我边上,害得我不得不英语解释我在做什么,思路一下子就乱了。不过,少了面试的压力,这时候和人用英语Pair,效果还算可以接受,至少我还可以思考。实在不理解的,就让自己的Pair多解释几次,好在ThoughtWorker们都是很好的人,我的Pair总是不厌其烦的为我解释,直到我确切的直到了我们要干什么。
在这个项目里面,我很高兴的扮演起学生的角色。一方面,我们不是很了解需求,需要向“过来人”学习,另一方面,来这边工作的两个Dev确实都有很长时间的工作经验。和他们在一起工作,我乐得把控制权交到他们手上,自己虚心的观察他们如何思考,如何解决问题。和他们在一起工作,会让人感觉很放心。正如我在《与高手共事》中提到的,他们做的那些工作都很简单,经过一步步简单的工作,一个个Story就完成了。
对我来说,这个项目才开始一个星期,已经学到了不少的好东西,值! -
2008-04-21
ThoughtWorks CodeJam
周末没得闲,因为参加了一次CodeJam。
CodeJam,是公司组织的一个编程活动,就是要在周末两天时间内开发出一个东西,据说此类的活动在其他的办公室举办过。这是我第一次参加类似的活动,参加这次活动的Dev都是公司内比较优秀的程序员,平时很难把这些人都放到一个团队里面,有机会和这些人在一起工作,本身就是一件令人期待的事。
这次活动的目标是为一个支援乡村教育的组织开发一个分享平台。在活动开始之前,我们对需求一无所知,所以,几乎就是看两天内能够写出多少东西。因为这个项目要开发的是一个Web应用,从生产率的角度来看,我们当仁不让的选择了Rails作为开发工具,这也是我最近在学习Rails的原因之一。
万事开头难,这次CodeJam也不例外。在一群Dev准备甩开膀子大干一场的时候,我们发现了一个问题,没有需求。需求,是冰云(BA)和QQ(QA)在之前一天和我们的客户谈好的。QQ在离开办公室之前,把从需求整理出的Story卡片锁到了自己的抽屉里,结果,第二天,她闹肚子了。好在冰云临危不惧,顶着我们的巨大压力,把部分Story重写了出来。直到QQ重新归队,打开宝箱,需求问题才得到了彻底的解决。
正式开工,场面那是相当壮观。一群ThoughtWorker,一群快手,一帮人抢着提交代码。做用户登录部分的高喊着,他们应该是第一个提交数据库表的,结果,更新代码时,已经有了数据库版本已经到了3。那是我和WPC干的,因为我们俩负责搭建开发环境,所以,先下手为强了。不过,我们高兴得有些过,用scaffold生成的代码出现了一个拼写错误。这时我们才发现,修改这些生成代码是多么痛苦的一件事。
在这里,我们用的典型的ThoughtWorks工作方式,一对Pair,拿到一张Story卡,然后,小步前进:测试、编码、重构、提交。正是因为步幅很小,所以,就出现了大家争抢着提交代码,因为稍微慢一点,就会更新下来一片代码,这种时候,便要重新运行测试。运气不好的话,破坏了别人的测试,还要帮别人修复。其实,在一个大的开发团队中,这种现象很常见,尤其是测试多到不能很快运行完,比如有集成测试的时候,常常是运行测试之后,又来了新代码。
典型的ThoughtWorks工作方式,还有另外一个含义。一群人一边写着代码,一边互相开着玩笑。在我的印象中,ThoughtWorks开发团队从来就不缺少笑声。其实,这次参加CodeJam的人,有很多我并没有直接在一起工作过,所以,这也是一个很好的了解大家的机会。比如,在我的印象中,WPC一直是闷着头写代码的家伙,和他Pair才知道,他原来也是那么有才,可以让人笑得肚子疼。至于像徐X和gigix这种平日里就给大家很多欢乐的家伙(也许也包括我自己)就更不用说了。当然,也有比较安静的,亮亮和来自加拿大的Ricky被我评为“最安静的Pair“。
两天下来,从无到有,一个具备基本功能的网站就建立了起来。showcase的时候,看着这个小网站,心里还是很有一丝满足的。对我而言,这是我第一次做Rails项目,第一次尝试用TextMate去开发。这次CodeJam,是在公司内部进行的,希望将来有机会把这个面扩大一些,让其他公司的人来和我们一起来做,一方面我们可以从其他人身上学习到一些东西,另一方面,也让别人了解一下ThoughtWorks是如何工作的。我相信在如何进行软件开发这个问题上,ThoughtWorks做得足够好。
UPDATE
其他的ThoughtWorker也有对这次活动发表了自己的看法。
冰云:Beijing Code Jam - 2 days agile development project
Ricky:CodeJam@Thoughtworks Beijing -
2008-04-18
Rails初印象
是的,我在学习Rails。
我所了解到的,大多数人是因为Rails而学习Ruby,像我这种了解Ruby却对Rails一窍不通似乎是异类。道理上来说,传统的途径应该是先学语言,再去了解相关的开发框架,像Rails这样喧宾夺主的情况,也算是异类了。当然,也正是因为Rails的喧宾夺主,才让人们有了更多的机会认识Ruby,了解Ruby的优雅。
趁着我还不那么了解Rails,把Rails留给我的初印象记录在这里,算是一个初学的记录。
Convention over Configuration(CoC),这是Rails广告给我留下的最深印象。这是一种改变业界对软件开发认知的思想。如同Spring让我们认识了Dependency Injection(DI),进而改变了我们的设计方法。Rails让我们认识到,原来有时候程序设计并不需要那么灵活。一片惊呼之后,效仿者蜂拥而至,人们纷纷尝试把这个想法带到自己熟悉的平台,其场面与Spring当年带来的DI容器热如出一辙。
如果Spring只有DI,它并不会带来真正的变革,同样,Rails也不是只有CoC。在我看来,CoC之外,Rails还集成了Web开发的实践。
Web开发实践有哪些?首当其冲的自然是MVC的架构,所以,在Rails中,明明白白的在目录结构上就把MVC分得清清楚楚。不过,我们还是抛开MVC这种路人皆知的答案,看一些具体的东西吧!
用Java写Web方面的应用时,我最担心的问题是如果一不小心上了某个框架的贼船,比如Servlet,结果就是为了看到自己程序能够正确运行,不得不把应用部署到服务器上。一旦出现了问题,解决问题就变成了一个非常低效的过程,因为我们不得不一次又一次的进行部署,大好的年华便随风而逝了。所以,对我而言,做Java应用的设计时,一个指导性原则就是尽量不依赖于任何框架,这样,就可以把真正的逻辑剥离出来进行测试了。初涉Rails,我也有类似的疑问。但我发现,原来Rails框架本身已经替你考虑好这个问题,它把测试的考虑也内建到框架之中,这样便可以很容易的针对每个Controller编写测试,而又不必理会部署的消耗。
Rails在测试方面有很多的考虑,它清楚的分出为Model而写单元的测试,为Controller而写的功能测试和跨越Controller的集成测试,而Fixture这个概念的存在,让我们很好解决测试数据的问题。这一切实际上都是一些优秀的软件开发实践。实际上,像这样的实践,Rails开发框架中还有很多,比如,如何处理页面布局、如何使用Ajax、如何管理数据库的迁移、如何让自己的应用Restful等等。使用Rails,不经意间,我们便可以走上一条正确的路。同许多开发实践一样,单独来看,这些做法本身并看不出多大的价值,但放到整个软件开发过程之中,便可以极大的提高开发生产率,尤其是在后期维护阶段。
不同于之前用过的一些框架,需要在实践中摸索正确的用法,Rails是第一个让我强烈的感受到开发实践内建其中的框架。只要走在Rails的道路(Rails Way)上,那么无论如何都不会偏离正确的方向太远。正确的道路何在?不得不提起《Agile Web Develpment with Rails》(中文版《Web敏捷开发之道》)。技术,常常是养在深闺无人识。其实,这个世界上一点都不缺好的想法,好的做法。我们经常会看到一些新东西让我们感慨,原来还可以这么做,但是,大多数时候,我们并不知道这些东西的存在。这本书的出现,恰到好处的向人们展示了Rails的优秀,比如前面提到的那些实践。不同于很多板着面孔教育人的计算机书,这本书轻松愉快的把一个完整的开发过程展现在人们面前。大多数人几乎是同时认识这本书和Rails框架的,所以,几乎一开始,Rails一族便走在正确的道路上。
不过,Rails还很年轻。年轻的结果就是不稳定。《Agile Web Develpment with Rails》第一版和第二版之间号称有70%的变动,而Rails 2.0又让第二版中的程序遭遇起步停车,一开始便会有差异。有些时候,这会打击初学者的积极性,也会让希望采用Rails的企业望而却步。
这便是我对Rails的初印象。







