读书时间:《软件开发沉思录》
《软件开发沉思录》,参与了翻译,出版也很久了。但上个礼拜才拾起来,今天才把整本书读完。
13个来自不同职位、不同角色的ThoughtWorks员工成就了这样一本书–可以说,非常精彩。
看完这本书,第一个感觉就是公司知识和文化的传承做得充分到位。因为读很多章节,都会联想到自己在曾经或者现在项目中遇到的问题和解决方案,它们是何其的相似。第十二章-一键发布,我们在曾经的项目里面就完美地实现了。第十四章-实用主义的性能测试,我甚至很想厚着脸皮说:我们实际上早就已经超越了。
第四章-语言的盛景,让我们看到一个百花齐放的时代,这不,Google刚刚发布了它自己的语言Go。同时,随着并发的需求越来越强烈,也让我下定在今年学习一门函数式语言的决心。
公司老板在第二章里面就开宗明义的说到:敏捷过程的价值,就在于减少从“提出业务需求”直到“软件上线来满足业务需求”这两个端点之间所需的时间与成本。但这不妨碍也不冲突一个软件开发人员拥有一些艺术上的追求。在整本书中,我最钟爱的就是第六章–对象健身操。这个章节的内容并不算新,它们都可以在前人的一些书籍中找到,比如《重构》、《设计模式》等。但作者巧妙得总结出一套简单的实践和易记但深刻的经验来支持程序员写出优质的代码。如果说《重构》、《设计模式》等是基石,那么对象健身操就是一套在基石之上的简单的工具集合。
总的来说,这本书,值回票价!
《ThoughtWorks文集》中译本序
这本《 ThoughtWorks文集 》中译本面世之际,也正值“敏捷中国2009大会”召开在即。两者可谓相得益彰。
从 2004年进入中国,ThoughtWorks见证和参与了中国敏捷社区的发展历程:从五年前的筚路蓝缕,到如今的欣欣向荣。更令人欣慰的是,在原则、价 值观等“大问题”上,敏捷的实践者们已经基本达成共识,社区的话题更加趋于关注实践──这意味着敏捷社区正在步入成熟,将用他们的知识和技能为各自效力的 企业创造更大的价值。
我们在这个时候把《ThoughtWorks文集》翻译出版,是希望为社区的发展再尽绵薄之力。作为敏捷方法 的积极推动者,ThoughtWorks从多年、多个行业的实践中积累了丰富的经验。本书收录的13篇文章涵盖了编程技术、项目管理、持续集成、测试等方 面内容,将带领读者了解ThoughtWorks在软件生命周期各个环节所推荐的工作方式。
比较难得的是,这本《文集》不仅由 ThoughtWorks员工撰写,也由ThoughtWorks员工翻译。译者们或是与文章作者素有私交,或是在文章所论述的领域有所专擅,这也使得翻 译的质量更有保障。感谢这些译者在工作之余的辛勤翻译,才使这本《文集》如期付梓。他们是:韩锴,胡振波,金明,李剑,乔梁,熊节,徐昊,张晓庆,郑晔。
一本薄薄的《文集》当然不可能解决所有问题,我们更希望它能够收到抛砖引玉的效果。希望ThoughtWorks的经验心得能对国内的敏捷实践者们有所启发,帮助他们做出更多创新,创造更大价值。最后,希望你阅读愉快。
郭晓 总经理,ThoughtWorks中国公司
无关敏捷,关乎责任
JJG在《The Elements of User Experience》特别强调,要让每一个人参与到网站设计中:高层管理人员,市场人员,销售人员,等等。不过这里,我想他忽略了一个很重要的群体,就是开发团队。
《The Elements of User Experience》把用户体验分为五个要素: Strategy, Scope, Structure, Skeleton, Surface。
其中最根本的是strategy,因为它是用户的需求和网站的目标。
在我们的开发过程中,拿到一个story并不意味着开发的开始,而往往很多时候我们会花很多时间论证这个story的价值所在。开发团队经常会向客户提很多问题,探究这个story的起源和目的;开发团队经常和客户一起讨论甚至争论一个story的功能或者设计,因为随着开发的深入,对项目的了解,我们有义务告诉客户我们所想,帮助客户找到真正所需。
讨论的结果可能证明开发团队是错的,也可能证明客户是错的。但双方都在讨论中对story的价值越加清晰。
因为通过争论,客户会发现
- 其实这才是我们真正想要的:经过向公司相关人员咨询,发现这果然是更好的方案。
- 原来可以通过这种更简单的方式得到我们想要的,得到用户所需要的。
- 应该丢弃这个功能,这样做是错的,这样的设计不仅对我们未来的业务发展没有好处,而且还可能成为一个束缚。
- ……
开发团队:
- 的确客户是对的,我们在实现的东西是有价值的。
- 又一次不仅帮助了客户找到了真正的价值,也避免了让自己花很多时间做一个用户不会喜欢的功能。
- ……
印象特别深刻的是在项目结束之后,客户的BA诚挚地对我们说:谢谢团队的每一个人,谢谢你们不停地问问题。
后面的那句话,我想,是他们意外得到的。所以在感谢的时候特别地提了一下。
开发团队保证正确实现客户所要的,就够了么?不,开发团队要保证正确实现客户真正想要的。
这里无关敏捷,这里关乎责任。
The Elements of User Experience
AgileChina 2009: Pragmatic Agile
由在敏捷领域最具有影响力的技术社区InfoQ中文站、敏捷方法论的领导厂商 ThoughtWorks共同主办的敏捷中国技术大会(Agile China 2009),将于9月11日~12日(周五、周六)在北京举行。届时将有超过500人来自电信、金融、互联网、教育等行业在内的高级软件开发人员、项目管 理人员等参加。本次大会将特别邀请敏捷宣言缔造者、敏捷编程(XP)方法学创始人Kent Beck,敏捷开发权威人士、敏捷宣言的创始人之一,Dave Thomas,敏捷宣言签署人之一Steve Freeman等国际敏捷领域专家,以及在团队中成功应用敏捷的阿尔卡特、赛门铁克、诺基亚-西门子、华为、腾讯等公司的项目负责人参与此次大会并分享他 们的心得。
敏捷中国技术大会(Agile China 2009)是国内敏捷技术领域最高水平的大会,本次大会将由InfoQ中文站负责大会策划、营销和项目实施。InfoQ中文站在今年4月已成功举办了 QCon全球企业开发大会,邀请了国内外30多名讲师,超过550位架构师、技术总监、项目经理和高级工程师参加了本次大会,大会及其运营团队获得了空前 的好评,并誉为国内”技术含量最高”的大会。而今年的敏捷中国技术大会,也将一改往年的风格,参会者以高端开发者和技术管理者为主,融合管理和工程实践, 推广全面敏捷之路。
会务咨询: 010 – 89880682 agilechina@cn.infoq.com
赞助咨询: 010 – 89880682 sponsor@cn.infoq.com
出发
虽然工作了这么多年,但还没有在一个正式的项目从头就开始参与的经历。
工作以后的第一个实验项目是在Trilogy University的手机B2C网站,算是从开始就参与,但当时懵懵懂懂,没有太多的感受。后来陆陆续续在Trilogy做了几个项目,都是从半路杀进去。到了TW,做了两个项目,也都是在项目的中途加入。
虽然这也有好处,比如提升了在已有代码基础上如何快速上手,改进既有架构设计等能力。但没有从头开始参与过一个项目,总有种人生不完整的感觉。再优秀的框架,也是别人先搭建好的。从头开始做项目所能经历的事情,比如工具的准备,环境的搭建,架构的设计,需求的摸索,客户的初期沟通等等,都是陌生的。
把一件东西从无到有搭建起来,这不免让我期待这种机会。
这不,它来了。
这次项目的客户是一个旅游网站,本来有机会去澳洲做inception,但因为种种原因没有成行。倒不可惜,因为在项目正式开始之前,我们就忙碌着做准备工作了。说实话,我更庆幸澳洲没有成行,准备工作不失一些很有价值的东西。虽然不见得带来技术能力提升,但至少经历过了。
Web认证方法探视,Git学习,机器安装和环境准备,用Ldap实现Web认证,JRuby,Restlet….
这个过程像是在黑暗中前行,有点担忧,但随着跟客户的沟通、以及准备工作的积极进行,目标正一点点变得清晰。原先拿到proposal时的一头雾水已经消失,心里也越来越踏实。这个过程也有一丝丝的兴奋和成就感,应用什么技术、使用什么框架、搭建怎样的环境,都成了我们可以决定的事情。
下个礼拜项目就要正式开始了,经过几周的准备工作,团队正蓄势待发。出发吧,唱着亡命之徒。
乘时间机器,看敏捷旅程
BOSCO系统是一个在线品牌管理系统,此项目的客户是一家跨国酒店集团,旗下拥有多个世界著名的酒店品牌。BOSCO系统将服务标准化、标准符合度审 查、改进流程管理等酒店品牌管理的工作内容整合到一个信息系统中,来提高相关人员的工作效率。目前BOSCO系统已经被全球十个酒店品牌、超过1000家 酒店使用,用户超过8000人。
BOSCO系统的开发基于Ruby On Rails,在项目的开发过程中应用了敏捷开发方法。在开发此系统的8个月中,经历了15个迭代和3次发布。通过这种与客户紧密合作的工作方式我们按时交 付了系统,并得到了客户的高度认可。笔者作为开发团队的一员,从开发者的角度对基于Ruby On Rails的敏捷开发实践总结出一些心得体会,其中有成功的经验,也有失败的教训,愿与敏捷开发爱好者分享。
在我们的系统中,有一个有趣的类,叫做TimeMachine,用于修改UAT服务器的系统时间。但现在,让它带我们穿梭时空吧。
TimeMachine.go_to(”2008-04-15″)
半路接手 关键字:Knowledge Transfer,结对编程
2008年4月,BOSCO系统漂洋过海来到中国。此时,它已经在美国经过了3个月的开发,且完成了第一次发布。现在要开始它的移植过程(从美国团 队的大脑移植到中国团队的大脑)。给我们的资源并不多,只有3个项目原有工作人员:一个BA(业务分析师),两个Dev(开发人员)。但时间却相当有限: 一个月。
虽然BOSCO系统的开发时间并不长,但Rails强大的表现力使系统已经足够庞大到让我们担忧Knowledge Transfer能否在约定的时间内完成。而且中国的开发团队中,真正有Rails开发经验的只有一人。如何在这么短的时间内,掌握这么庞大的系统,成了 摆在眼前的挑战。
我想很多遇到过此种情况的开发人员都不会对以下几种经历感到陌生:
- 阅读大量关于系统原理和项目架构的文档,但它们并不能直观、准确地反应项目情况。
- 参加各种标榜着“Knowledge Transfer”且耗时长久的会议,但收益甚少。
- 独自面对系统时不知从何下手,不断地寻求原有开发人员的帮助。
- 由于不熟悉系统造成在开发过程中不断犯错,贡献了很多“垃圾”代码,并影响了系统开发进度。
其实对于开发人员而言,掌握一个项目最重要的是提升对项目本身的“熟悉度”。此熟悉度代表对陌生的技术知识,代码的编写风格,开发的习惯,程序的架构,环境的搭建等等的掌握和了解。而结对编程是快速掌握这些知识技能的秘诀,还是拿事实来说话吧。
两个礼拜之后,作为先行和两个美国Dev结对的同事已经能够带新人了,而且开发速度不亚于两个美国 Dev。短短两个礼拜,中国团队对项目的整体架构,不说了然于心,但也是熟门熟路了;对于一些story,也能得心应手开始实现了。这是我们自己也预想不到的速度。
之所以能在如此短的时间内掌握项目,就是拜“结对编程”所带来的好处所赐。有人会说,结对编程到底有什么魔法?其实没有魔法,它只是简单地实践了很多人都 懂得的道理:学习一件东西最快速的手段就是动手去做。而结对编程,不仅能让你有立即动手去做的机会,而且边上还有个让你观察学习、给你指导的老师。这是我 对结对编程的初次体验,让我非常兴奋。还记得一个朋友给我电话告诉我“项目中的新人不能快速掌握知识的问题”时,我告诉他:不要犹豫了,结对编程吧。
结对编程在ThoughtWorks是一种常态,它作为敏捷开发中一项备受推崇的实践也已经被业界所熟知。但真正开始实施的公司并不多,这是一种奇怪的现 象,但同时也是可以理解的现实。首先是因为未有机会体验结对编程美妙的开发团队或许还有所疑虑,其次是来自老板、客户等非开发人员的压力。 Knowledge Transfer作为每个团队都可能会经历的事情,不失为开始尝试结对编程的好时机。我相信,一当你开始尝试,你就不愿意停止。
TimeMachine.go_to(”2008-05-15″)
加速前进 关键字:最佳实践
随着Knowledge Transfer期满、美国同事离去,客户一度很担心中国团队能否掌控项目,能否保持开发速度。但在快速接手项目之后,项目开发随即进入了加速通道。在完 全接手项目的第一个迭代之后,中国团队已经赶上了美国同事的开发速度。在这个过程中,除了因为团队的快速学习能力之外,还有我们保持的一些最佳实践让我们 赢得了胜利。下面,让我简单介绍其中一些。
一致的开发机器:我们有6个开发人员,也就是3对pair。Pair的3台机器都是漂亮精致的Mac Mini。当然这不是重点,重点在于,3台机器都有一致的开发环境:一致的程序目录,一致的安装软件,一致的快捷命令等等。完全一模一样的配置使pair 在进行切换时,不会对另外一台机器感到丝毫的陌生,这有助于开发人员迅速进入开发状态。
快捷化常用命令:在开发时,我们每天都要进行无数次相同的一些操作:进入rails开发根目录,启动web server,签入代码等等。比如当你要进入rails开发目录,你就得打入命令:cd /Users/rails/workspace/bosco/rails_root。这是一个简单的命令,但同时也是一个繁琐的命令,特别是当我们每天要 进行多次这样的操作时,就会浪费大量的时间。这时,如果你为它加一个alias,把这个枯燥的操作用一个简单的命令”rr”代替,它会帮你节省多少时间 呢?效率的提升有时就在于一些简单的事情。
不做简单重复的劳动:每天的工作总会有一些事情需要简单重复的劳动。比如当你要验证一项功能时,你需要手工打开网页,然后按 着流程一步一步操作,来看实现是否正确等。而每当此时,我们的选择是:绝不做简单重复的劳动,而是实现一个自动化的脚本来帮助我们进行这些操作。自动化不 同的任务,可以选择不同的工具,比如selenium,ruby,shell等等。后来我在《The Productive Programmer》中读到Neal Ford大师如是说:“手工执行简单重复的任务会让你变傻,会消耗你的注意力,而注意力是最重要的生产力之源。找出一种聪明的方法来自动化这些任务,这会 让你变得聪明,因为你能从中学到一些东西。”
每天早上的code diff:在早晨的站立会议结束后,我们并没有马上着手清扫story。所有开发人员 会挤在一台机器前,查看前一天的code diff。大家会看到所有成员在前一天的工作中修改的代码,相关的开发人员会对自己的代码作出解释。当有人对一段修改有疑问时,我们就会对此段代码进行讨 论。或者是实现上的一些逻辑漏洞,或者是一些不规范的代码编写,或者是一些可能的性能改进,我们总能对一些代码提出疑问,并提出改进意见。Code diff过程是对站立会议以及结对编程的补充,是对代码质量的进一步检验,有助于团队对代码的了解,也促进了代码质量的提升。短短十分钟,何乐而不为?
每周的技术session:每周的技术session是我们一直保持的良好传统,团队从中受益匪浅。项目中总会遇到一些难题,或许是 一种陌生的技术,或许是一个难解的问题。而此时,总会有人站出来说:“让我来讲讲这个吧”。或许这项技术对于主持者也是完全陌生的,但不要紧,接下来一周 紧张的学习已经足够(这也会促使他更加快速地学习)。一周之后,主持者就为我们带来了一道“丰盛的大餐”。在session中,团队成员都会踊跃发言,并 乐于抛出任何疑问让大家讨论。讨论是最能产生火花的,来自每个人不同的思考会让你对问题了解得更加深刻。讨论帮助我们解开了一些困扰已久的疑问,并加深了 对一些技术的理解,比如:CSS,Memory Cache, REST, Ajax,Ruby的对象模型等等。通过技术的讨论和学习,团队成员的整体开发能力得到了提升,这极大地促进了项目的开发速度。
团队需要勇于尝试一些实践来促进团队的开发效率和提升团队的整体能力。上面所提及的有些实践都是我们在平时的工作中摸索、体会和总结出来的。比如每周的技术session,就是在成功地开展了一次之后,被保留和坚持下来了。
如何发现一些值得尝试的实践?这看似很难,其实很简单。在项目中遇到的问题,工作中偶然发现的一些事情,别人的经验,或者是你自己的一些想法,都可 能是对一项实践的启发。你唯一要做的,就是勇于尝试。“从来没有人这么做过”,或者“别人都不这么做”不是你不能这么做的理由。
TimeMachine.go_to(”2008-08-01″)
挑战难题
当项目开发进入第5个月,我们遇到了一些真正的困难,它们分别是“历史”story和系统性能优化问题。
当项目遇到困难时,正是审视敏捷实践的最好机会。TDD,简单设计,持续集成,重构等等,让我们看看这些实践在项目开发中显现的力量吧。
笑看历史 关键字:简单设计,TDD(测试驱动设计)
历史story:作为全球质量管理员我要查看一个酒店的标准审查历史记录从而跟踪并比较酒店在各个时期的标准符合度。
简单分解一下这个Story,它要求提供的功能是:
- 系统在一些比如标准变化,酒店审核等事件发生时能保存当时的数据
- 系统应该提供一个界面,让用户通过选择特定的日期查看历史信息。
跟通常一样,我们经过estimation(当时估的是5个points,并不太大),以及tasking(简单的设计)之后,并开始实现这个story。
刚开始,这个story如预期一样顺利地开发下去了。一天,两天,到了第三天,我们突然发现在实现一些功能时有点举步维艰。但通过一些“邪恶”的手段,我 们还是解决了那些问题,虽然觉得那样的实现并不是最佳实现。到了第四天,在实现另一些功能时,我们陷入了绝境:实现的过于复杂让代码改动极其困难,通过了 这边的测试,那边的测试就失败了,如此反复。还差两天迭代就要结束了,这个story却深陷泥沼,团队陷入担忧之中。这时,正如团队一成员所说,忍无可 忍,让我们重新跳出来看一下原来的设计吧。
基于实现中遇到的困难,我们讨论了原先的设计,发现了其中的一些缺陷,并迅速找到了一个更好的设计。新设计雏形初具,再次动手吧。改动代码,很多原先的测 试应声失败了。好事情,失败的测试告诉我们哪里出了问题,过去修正那些失败的测试吧。红,绿,红,绿,按照这样的节奏,出乎所有人意料的事情发生了:一个 下午,仅仅是一个下午,我们把历史story完成了!
因为这个设计并不在技术层面,而在业务层面,所以在这里我并不想多讲story的详情。但发生这样的问题,是否会让你怀疑敏捷实践“简单设计”呢?如果你有此怀疑,我的想法就正好跟你相反,因为通过这个story让我更加相信“简单设计”的好处。
首先,即使现在回头看,我们还是认为就算当初花几倍的时间去做设计,也难免犯同样的错误。其次,检验设计优劣的最佳工具就是代码本身,及早地应用设计于代 码,让代码来告诉你设计正确与否。这正是在这个story陷入泥沼时我们的反应:实现不能继续,来看看设计的问题吧。再次,之后我们的设计之所以如此成功 地符合了业务的需求,是因为前一次失败的经历让我们对代码有了更进一步的了解,对问题有了更清晰的洞察。谜团是在行进中解开的,并不是一开始就能知晓。最 后,我想我们唯一应该改进的,就是在发现开发出现困难时,能更早地跳出来,从设计角度分析一下问题。
新的设计实现能在一个下午完成,是因为高测试覆盖率为正确的重构实施提供了安全保障。测试总能迅速地提醒我们哪些地方出了错,以保证重构的正确。其 次,良好的代码结构,也是代码能如此快速地修改完成的原因。这些都是TDD开发带来的好处,TDD开发不仅能提供高测试覆盖率,也能带来良好的代码设计。 这就是越来越多的人把TDD称之为测试驱动设计(Test-Driven Design)的原因。
TDD给设计带来的一些好处:
- TDD迫使你在编写代码之前,考虑更多对象之间的交互。
- TDD迫使你把对象的创建封装在一个更好的层次上。
- TDD会让你写出更加小而内聚的方法,从而使方法的重用以及纠错变得更加方便、快速。
百倍加速 关键字:性能,重构,YAGNI
随着项目进入后期,功能的开发已经基本完成。此时,我们面临的是系统的性能问题:发布一个标准竟然要5个小时,这是不能忍受的。由于发布标准需要在一个事 务内完成,而且它需要修改大量数据。所以在这5个小时内,数据库的很多表都被锁定,系统几乎处于瘫痪状态。于是,顶着巨大的压力,我们开始了性能优化之 旅。
先通过添加日志找出最耗时的操作,然后仔细地跟踪和分析这块代码。我们随即发现了一个需时十分钟的操作,这个方法的时间复杂度是n2。但这段代码犯了一个低级错误,它可以被优化成一个n复杂度的方法。立即修改,修改后由于消除了大量重复操作,它的耗时竟然不超过一秒。“秒杀十分钟”就这样诞生了。随着我们进一步的跟踪和分析,多处设计上的问题暴露出来了。几天的改进之后, 5个小时的操作缩减到了1个小时。
但显然,一个小时的操作还是不能为客户所接受的。于是,继续优化。马上,我们就发现标准发布操作对很多标准都进行了重新算分,但实际上只需对有改动的标准 算分即可。而没有改动的标准,可以把它的得分结果存于数据库,下次用到时从数据库读取即可。通过这个“缓存”,我们再次大大得提升了速度。运行之,整个操 作竟然只需5分钟!5个小时的操作,到现在的5分钟,百倍加速也!
这个性能优化问题是个典型的案例,它给了我们很多启示。首先,在遇到性能问题时,先别忙着埋怨平台的速度,还是先看看设计里面存在的问题吧。其次, 也是我们可以改进的一点是:在TDD“红-绿-重构”的标准开发节奏中,如果我们多花一点时间在“绿”之后进行重构,就可以避免犯一些低级错误。
或许有人会说,如果你在刚开始就做更多的设计就能避免到最后出现这样的性能问题。但我想说,非也,你忘了:你将不需要它(YAGNI)。预想开发是 个迷人的陷阱,或许可以在刚开始就花费十倍的时间去避免这个性能问题的产生。但问题时,在刚开始你怎么知道哪些是必要的设计,而哪些是浪费呢?敏捷团队注 重的是给客户创造真正有价值的业务,而不是花费大量时间去制造一个“华而不实”的系统。
“只在确实需要时才提供功能”,这是我们遵循的准则。
最后,性能改进之所以如此顺利,得益于我们遵循的一些敏捷实践。比如TDD带来的高测试覆盖率,保证了重构的正确性。在BOSCO项目的开发中,不 乏这样的大型重构,我们从不害怕修改代码,因为有坚实的测试代码为重构撑起了安全网。而反之,重构促进了代码结构的优化,提升了系统性能。
从这两个问题我们可以看到:
- 敏捷实践促进了系统设计的灵活,代码结构的优化,系统质量的提升。
- 各项敏捷实践之间其实是相辅相成,相互促进的。
BOSCO脚印
说了这么多,让我们来看看BOSCO系统的真实代码状态吧。
+————+——-+——-+———+———+—–+——-+
| Name | Lines | LOC | Classes | Methods | M/C | LOC/M |
+————+——-+——-+———+———+—–+——-+
| Controllers| 1923 | 1602 | 35 | 232 | 6 | 4 |
| Helpers | 1451 | 1210 | 8 | 206 | 25 | 3 |
| Models | 4332 | 3551 | 63 | 566 | 8 | 4 |
| Libraries | 2810 | 2337 | 37 | 237 | 6 | 7 |
+————+——-+——-+———+———+—–+——-+
| Total | 10516 | 8700 | 143 | 1241 | 8 | 4.5 |
+————+——-+——-+———+———+—–+——-+
Code LOC: 8700 Test LOC: 12962 Code to Test Ratio: 1:1.5
(注:由于rake stats对rspec的统计失准,故略去。对于测试代码的总量统计,可见Test LOC。同时,rake stats只统计ruby代码,而不包含html,javascript等其它代码。)
另外,从四月到九月的5个月中,共提交代码2400次。
我们可以从以上数据看到:
- 代码设计的优良:平均每个类不超过十个方法,每个方法不超过五行代码。如果除去特殊的Helpers模块,平均每个类不超过7个方法。
- 高测试覆盖率:测试代码与功能代码的比例是1.5:1,行覆盖率达到90%以上。
- 开发人员的熟练度:每对pair每天6次的提交速度足以证明开发团队对于系统的熟悉度。
另外,考虑到Ruby On Rails作为特别擅长开发Web应用的框架所具备的强大表现力,我们相信此系统的复杂度不亚于很多规模在十多万行代码的系统。
TimeMachine.go_to(”2008-09-17″)
时间定格在BOSCO项目第三次发布的那一天。除了需要一段时间的bug修复和数据准备之外,发布并没有给工作带来太多不同。我们从未因为发布的到来而惊 慌,也从未在发布时忙得不可开交。正如团队一成员所说,每次我们都是在等待发布,安静地等待着发布的到来。因为合理的安排和控制,让一切尽在掌握中。
发布成功,欢呼之余,让我们回头看看项目中的哪些实践保障了发布的顺利完成吧。
客户协作 关键字:PM、BA,还有Dev
曾经有一个同事突发感想说:“在ThoughtWorks做程序员是幸福的”。这不禁让我有很多感触,是的,在ThoughtWorks做程序开发 是一件幸福的事情。当你有任何关于业务逻辑上的疑问时,坐在身旁、招之即来的BA总能给你准确地解答;当你坐着投入地进行开发时,可能你从未想过,之所以 有这么良好的环境,是因为PM帮你阻挡了一切不该有的干扰。
PM和BA在背后付出的需求分析、客户交流等工作,让开发人员能把大多数时间和精力花在编码上。
BA在每天的站立会议之后,会有一个跟客户之间的BA站立会议。在这个会议上,他们会讨论各个业务的细节,力保每个业务细节的正确性。正是业务的正确性,让每天的开发工作能顺利进行。
PM每天会用很多时间跟客户交流项目进度,确保客户了解项目状态。并在每天工作结束之后总结一封报告邮件,这封邮件包含了对一天工作的总结,各个story的进度情况等。通过这封邮件,客户能及时地了解进度情况。
那Dev能在客户协作方面贡献什么呢?有人觉得,开发人员的任务就是从BA那里拿到story,并严格按照需求开发,而无需做与客户协作沟通等工作。其实 这并不准确,Dev完全可以在客户协作方面发挥自己的作用,因为对于整个系统架构的了解,Dev有时候比BA,甚至比客户自己还了解他们真正需要的是什 么。当我们拿到需求时,我们可以从开发者,以及整体系统架构设计者的角度考虑一下需求的可行性、必要性。有时我们会直觉有些需求并不是客户真正想要的,或 者我们可以通过另外更简单的方式给客户提供同样的功能。经过一些分析,以及跟BA的讨论之后,BA通常会接受我们的观点并与客户进一步讨论。在这个过程 中,Dev起到了帮助客户认清真正需求的作用。这是一个双赢的结局,开发人员不需要为一些无必要的功能而增加不必要的工作,影响架构的稳定性;同时,客户 可以不必为一些价值不高,甚至没有价值的功能而付出昂贵的代价。
所以,客户协作并不只是PM和BA的工作,Dev作为系统的开发者,应该从他们的角度帮助客户找到对客户真正有价值的业务。
同时,信任,是客户协作的基础。团队与客户之间只有真正信任了,才能更好地合作。我们和客户之间的相处,就如朋友,在平时的工作中甚至会经常拿对方开开玩笑。
团队合作 关键字:Retrospective,Feedback,持续改进
大家都说,这是我们呆过最开心的一个团队,因为从不缺少欢声笑语。而我觉得,这更是一个正直的团队。无论谁有优异的表现,我们从不吝啬赞扬;无论谁犯错时,我们也会毫不犹豫地指出。
每两周一次的retrospective提供了一个寻找团队问题的好机会,在每次的回顾反省中,我们都会找出一些项目中的问题,并在接下来的工作中给予改进。这样团队才能保持持续的进步。
有人会问,为什么在我们的团队中就不能保持这样良好的气氛,无法保持正直的态度呢?究其深层次的原因,首先需要公司的制度让团队的成员处于平等的地 位,不应该有谁是在“管理”谁。PM,BA,Dev之所以需要不同的职位,只是因为工作类别不同而已。PM负责管理客户期望,BA负责需求分析,而Dev 负责的是项目实现。
其次,团队作为一个整体,不应为任何问题追究到个人,而应把它归为团队集体的责任。
平等的地位和责任集体所有制,会让每个成员更具主人翁精神,也会让团队更加紧密地凝聚在一起。
团队成员的相互信任和紧密合作是项目成功的根基。
TimeMachine.go_to(“Future”)
敏捷方法并没有高深的理论,有的只是一些简单的实践。正是这些简单的实践,提升了开发人员的效率,促进了项目质量的提升,保证了项目最后的成功。
在未来的路上,让我们一起寻找更好的敏捷实践吧。
– 发表于《程序员》杂志2008年11月刊。
翻译这事儿
在团队的合作之下,终于完成了《The Productive Programmer》的翻译,值得庆祝一下。从开始到完成,经历了几个月的时间。对于我个人来讲,也投入了多个周末以及晚上的时间,甚至几次通宵达旦,这是个挺辛苦的过程。翻译完成,如释重负。
谈谈翻译这事儿。
首先当然得具备一定的英文能力,只有真正理解了作者的意图,才能进行正确的翻译。这是前提。
其次,也是没有翻译经验的人很大的一个误解,其实翻译更加需要的不是英文,而是优秀的中文能力。平白直叙,不追求质量的翻译当然很简单。但既要准确地翻译出作者的意图,又要生动地用中文表达出来,这不是件容易的事儿。我对翻译的每一章都经过了至少三个流程:1. 翻译成中文,2. 翻译完成一段之后再重新阅读整段文字,看是否通顺,并进行修改。3. 翻译完成一章之后,再次通读,使整章文字保持节奏的统一。但实际中,经过的流程更加繁多。10页的章节,往往得花费几个晚上的时间搞定,就很能说明问题了。翻译完成整本书之后,还需要再次通读全书,以统一所有名词,并再次确认所有章节是否保持统一的“调子”。
最后,也是翻译中最关键的一点,我想,是责任心。我在想,是什么让我不厌其烦反复地在推敲一段文字,一个句子,甚至是一个名词或者动词的使用?是责任心。只要有责任心,我们就能翻译出高质量的书。
翻译是个耗时耗力耗脑的过程,可以说有点“痛苦”。但真的非常庆幸能有这么一段经历,不仅锻炼了我的耐力,也让我的中文能力有了很大的提高。谢谢一起合作的所有同事们,特别是熊节。我想,熊节之所以能翻译出这么多好书,最重要的是他的负责任心态!
再次强烈推荐这本书,在我的博客中有很多《The Productive Programmer》优秀章节的摘抄,这确实是一本让我惊叹的好书。翻译,需要比阅读花费不低于数量级的时间,这也让我有机会反复琢磨书中的要领,学到不少非常有价值的东西。
Strawood Footprint
Project:starwood
Team members:
| Name | Lines | LOC | Classes | Methods | M/C | LOC/M |
+———————-+——-+——-+———+———+—–+——-+
| Total | 25806 | 21376 | 145 | 1243 | 8 | 4.5 |
+———————-+——-+——-+———+———+—–+——-+
Code LOC: 8602 Test LOC: 12774 Code to Test Ratio: 1:1.5
Next station:
E&P
Who have made a difference?
Forrester analyst Carey Schwaber published a blog post this week titled “Which Vendors Have Made A Difference In App Dev?”
Sun, by making Java a platform as well as a language and by making it bigger than Sun itself by opening it up with the Java Community Process.
ThoughtWorks, by pioneering Agile practices on complex enterprise projects and proving that Agile isn’t just for simple Web development.
iRise, by waking the market up to the limitations of textual requirements and providing an accessible and effective alternative.
Agile China 之 精益之旅
听了精益工厂之旅的演讲,个人有几点有趣的思考:
1. 环境越干净,不好的东西越容易被发现。
2. 人往往涉及面越多,权限越大,犯错的机会就越大。
3. 人没有机器高效,准确,但人的优点在于能发挥主观能动性。
其实人类社会也是如此:
干净整洁的社会环境:让一切不应有的地下交易都被放到阳光下,社会的黑暗才会越来越少。
完善的社会制度:用制度来限定人的权限,减少潜在的破坏,错误和浪费。
自由:在遵循社会制度的前提下,每个人都应享有最大的自由。自由催生人的主观能动性,推动社会的进步。
什么是精益?这篇文章我觉得很好。


