读书时间《咨询的奥秘 – 成功提出和获得建议的指南》

《咨询的奥秘》很早以前看过一遍,似懂非懂。虽然那时候我没有做过咨询工作,但感觉它讲的其实就是人与人相处、沟通的道理。成为一个咨询师之后,重新拾起再看了一遍。于是我真的明白了,这还是人与人之间相处和沟通的问题。不管你做的职业是否被称为咨询师,其实你在很多时候都充当着咨询师的职责,比如那个教作者种花的农夫。

权且允许我做一些粗浅的点评。

咨询第一法则:无论客户和你说什么,问题始终存在
咨询第二法则:无论问题最初看起来怎样,它始终是人的问题
咨询第三法则:不要忘记客户是按时间付费的,而不是解决问题的程度付费的

评:没有客户愿意承认他们存在问题,他们“只是希望你帮助他们在原有基础上进行改进而已”。他们不会承认他们存在问题,他们更不会承认这是他们人的问题,既然他们没有问题,那么你就别指望他们按照“解决问题”的程度付费。

百分之十承诺法则:不要承诺会有百分之十以上的改进
百分之十解决法则:如果不小心取得了超过百分之十的改进,要保证这部分改进不会被注意到

评:已经说了,客户不会承认他们存在问题,如果你不小心帮他们解决了50%的问题,那你不是陷他们于不义吗?同样,对于任何向你寻求帮助的人,你在帮助他们的同时要给足他们面子,他们才会再次寻求你的帮助。

玛威法则:不论客户在做什么,给他一些其它方面的建议

评:咨询的力量,很多都源于此。你有没有经常感觉到被旁人”一点通”?让一个外来力量介入,就是要这个“一点通”。

赏识规则:如果你在意谁得到了赏识,你就永远不可能完成任何事
孤独守卫者幻想:如果客户没有表现出对你的赏识,那就假装他们对你的杰出工作感到震惊 — 但千万不要忘记这只是你自己的幻想,而不是事实

评:作为一个外来力量,在那种”孤独“的地方,总希望得到一些鼓励。而经常的,你并没有收到任何赏识。放下,这是第一要务,不要在意那些赏识,不要被它左右。自信,保持应有的自信以及清醒,这是第二要务。无论如何,作为一个咨询师,你要有力量相信自己。

舍比法则:如果他们没有雇佣你,就不要为他们解决问题

评:在不恰当的时候,主动去帮助别人,会起到相反的作用。记住,你只是咨询师,你的工作是在别人需要的时候帮助他们,而不要摆出一幅父母或者导师的样子。没有人喜欢被教育。

鲁迪芜清甘蓝规则:一旦你消除了头号问题,第二号问题就会升级
艰难法则:如果你不能接受失败,你就不能成为顾问
艰难法则的转换:失败一定是有可能被战胜的
很艰难法则:一旦你消除了头号问题,那么第二号问题就会升级
最艰难法则:帮自己甚至比帮别人还困难

评:没有人能消除所有问题,问题会源源不断,甚至有可能会失败。既然咨询师不能帮助客户解决所有问题,那么咨询师就要懂得在恰当的时候离开。

橙汁测试:我们能做这件事,这是所需的费用。

评:要得到别人的信任和尊重,不是信口开河,不能作践自己。

医学上第一大秘密:90%的疾病都会不治而愈
玛威第一大秘密:对能够自我治疗的系统,要温柔地处理
玛威第二大秘密:再三治疗一个能自愈的系统,将最终产生一个不能自愈的系统
玛威第三大秘密:每一个处方都有两部分:药物和确保药物正确使用的方法
玛威第四大秘密:如果他们以前做的没有解决问题,那么告诉他们做些别的试试
玛威第五大秘密:确保他们付给你足够多的酬金,以让他们能按照你说的去做。咨询中最重要的就是确定正确的酬金
玛威第六大秘密:知道如何不如知道何时

评:存在即是合理,即使在你眼里看起来多么不合理。不要去给那些本来挺好的东西去动刀,结果可能不是治疗而是破坏。在手术台上,作为主刀医师,你应该有足够的地位得到别人的协助,你应该懂得如何正确使用正确的药物,你应该知道在何时下刀,不然,手术就会失败。

伯登规则:如果你不能修改,那就把它作为特色
粉饰规则:如果你不能以之为特色,那就粉饰之
逆粉饰规则:如果什么东西被粉饰了,那它肯定需要被改善

评:咨询师的精力和能力也是有限的,暂时缓住客户有时候是必要的,但不要忘了那些问题还是需要被解决。

斯巴克斯解决问题法则:偶然解决了问题会妨碍我们找出谁是问题的制造者

评:解决问题是客户请你的原因,但解决人的问题才是咨询师的最终目的。

三的法则:如果在你的计划中不能想出三个可能出错的地方,那么你的想法就有什么地方出错了
泰坦尼克效应:认为灾难不可能发生的想法经常导致不可想象的灾难

评:永远要保持谨慎,头脑发热只会害了你

改变第一法则:是黄瓜变得更像腌菜,而不是盐水变得更像黄瓜
普瑞斯科特腌菜原则:试图经过长时间去改变一个大系统的小系统,最有可能它自己被改变

评:咨询师,你永远是个外来者。你要先做好改善,再想他妈的改变。

快餐谬误:没有不同加上没有不同加上没有不同,最终等于明显的不同

评:在该坚持的地方坚持,在该坚守的地方坚守。当你屡次不再坚持,不再坚守,可能你觉得无大碍,但是最终会产生大变化。

新东西法则:没有新东西会好用
潘多拉疹子:没有新东西会好用,但人们总是希望这次能有所不同

评:还是那句话,存在即使合理,先不要急着去做大改动,别给自己惹来麻烦。

水牛套勒:你能让水牛去任何地方,只要它们愿意去那儿

评:你永远无法改变客户,除非他们愿意自己改变,你能做的,就是让他们开始愿意改变。

营销第一法则:顾问处于两种状态之一:空闲或者繁忙
营销第二法则:获得客户的最佳方法就是有客户
营销第三法则:每周至少花一天时间曝光自己
营销第四法则:客户对你的价值,比你对他们的价值重要的多
营销第五法则:不要让一个客户的业务超过你业务总量的1/4
林尼生存法则:为了能对自己说是,就要能对客户说不
营销第六法则:最好的营销工具就是满意的客户
营销第七法则:放弃你最棒的主意
营销第十法则:营销是为了质量,而不是数量

评:无论是顾问,还是谁。在当前的人群中塑造你的口碑,才是最好的营销自己的方法。当然,良好的交际和沟通是非常必要的。慷慨也是必不可少的,没有舍,就不会有得。不要轻易去破坏关系,那些关系可能对于别人不重要,但对你来说很重要。

定价第一法则:定价有很多功能,金钱交换只是其中一种功能
定价第二法则:他们付给你越多,对你的爱越多;付给你越少,尊重越少
定价第三法则:金钱通常是价格中最小的部分
定价第四法则:定价不是零和游戏
定价第五法则:如果你需要钱,就别接受工作
定价第六法则:如果他们对你的工作不满意,就别拿钱
定价第七法则:金钱不仅仅是价格
定价第八法则:价格不是一件事,它是谈判达成的协议
定价第九法则:确定一个让你不会后悔的价格
定价第十法则:所有的价格都基于感觉,无论是你的还是客户的

评: 以正确的态度对待价格,以正确的方法利用价格。价格是你赢得的,不是别人失去的,是你给别人创造了价值之后应得的。基于此,要给自己设定一个合理的价格, 没有尊严的价格只能让你变得更加没有尊严。但你做的事情,一定要让这个客户觉得值回票价。价格是客户付出的,是他们在意的,你应该合理的利用这个作用,来 帮助咨询工作的成功,比如定金。

信任第一法则:除了你以外,没有人介意你让别人失望的原因
信任第一法则:信任花费数年才取得,但只消数月便可失去
信任第一法则:当人们不再信任你时,他们不会告诉你
信任第一法则:获得信任的技巧,就是避免使用任何技巧
信任第一法则:人们决不会说谎 — 在他们自己眼里
信任第一法则:信任你的客户,同时也要切牌
信任第一法则:永远不要不诚实,即使客户要求你这样
信任第一法则:绝不承诺任何事
信任第一法则:兑现你的诺言
信任第一法则:把它写下来,但要在信任的基础上

评: 建立信任是一件很不简单的事情,是一件需要始终如一的事情。但建立信任也很简单,就是不要给别人太多期望,同时始终坦诚地对待人和事情。不要耍什么技巧, 也不需要给自己找任何理由,那都没有意义。但是,信任,不是无条件的,信任的同时,你也需要合理地保护自己。用公开的方式防范别人作假的可能,用协议来保 护双方的信任。

农场教训:
决不用廉价的种子
精心准备的土壤是所有园艺的奥秘
时令是决定性的
扎地最牢的植物是那些自己发展自己根基的植物
过多浇水产生的只是娇弱而不是强壮
尽管你尽了最大努力,一些植物还是会死亡

评:咨询,是帮助人成长以及正确成长的职业。最重要的是在你离开之后。

不要在习惯中死去

忍受是可怕的,因为它会让你慢慢习惯,直至死去却不自知.

当进入一个新团队的时候,我发现有太多的事情不能忍受.

我不能忍受机器环境的不一致:   团队已经为此付出太多无谓的时间.测试在这台机器上跑过了,却在另外一台机器上失败了.

我不能忍受团队的低效:  有太多可以自动化的命令,团队却还在坚持使用手动操作.

我不能忍受没有code diff环节的工作: 因为我突然感到心虚了,因为我对团队中其他人所做的事情毫无所知.Code diff是一项比站立会议有意义多的行为.

我不能忍受回顾会议没有action list: 大家提出了各种担忧,但没有一项得以执行.

我不能忍受设计中的坏味道: 当我提出进行重构的时候,团队却以没有时间来推脱.我相信,设计中过多的坏味道就是当初的”没有时间”所导致的.要等到无可挽回的时候再来补救么?

我不能忍受以所谓的隔离为由让所有的测试都成为mock测试: 因为这已经成为一个公认的弊病,但团队还是听之任知.

我不能忍受团队的保守: 对于新建议缺乏开放的态度.

我更不能忍受团队的短视: 屡屡以工期为由放弃了可以带来长远好处的实践.

两个礼拜之前,当我跟团队提出这些建议的时候.他们的第一反应让我惊讶,因为他们觉得”我们做得挺好的,没有改进的必要”.当我再试图慢慢渗透时,他们终于承认了这些实践的必要性,但他们还是以”没有时间或者我们都知道就可以了”的目的推脱.

两个礼拜之后,当我对其中一些曾经的坚持慢慢妥协之后.有种感觉突然上来了:”就是这样的“.

我知道,我的坏味道已经出来了.我们团队仍旧没有实行code diff的实践;我也为项目贡献了越来越多的mock测试……

忍受到习惯了.这时候,离死期也不远了.

当第一辆车出现破窗户却对它置之不理的时候,越来越多的破窗户就会出现了.

大道理谁都懂,但没有行动等于什么都没有.

胡凯的敏捷之形和熊节的知易行难已经在述说着相似的故事,发生在不同地方的版本.

这同时又让我反思,在曾经我也已经很习惯的团队里面,是不是也有这些我们未曾发觉,或曾经发觉但最后已经习惯的坏味道? 我们曾经是否以开放的态度接受了别人的建议,还是以自我感觉”挺好的”而不加考虑? 绝对有!

团队及时彻底的反思,以及开放的态度至关重要.这是避免让坏味道成为习惯的根本.那如何做到反思彻底,态度开放? 先让下一次回顾会议成为一次真正的回顾会议!

出发

虽然工作了这么多年,但还没有在一个正式的项目从头就开始参与的经历。

工作以后的第一个实验项目是在Trilogy University的手机B2C网站,算是从开始就参与,但当时懵懵懂懂,没有太多的感受。后来陆陆续续在Trilogy做了几个项目,都是从半路杀进去。到了TW,做了两个项目,也都是在项目的中途加入。

虽然这也有好处,比如提升了在已有代码基础上如何快速上手,改进既有架构设计等能力。但没有从头开始参与过一个项目,总有种人生不完整的感觉。再优秀的框架,也是别人先搭建好的。从头开始做项目所能经历的事情,比如工具的准备,环境的搭建,架构的设计,需求的摸索,客户的初期沟通等等,都是陌生的。

把一件东西从无到有搭建起来,这不免让我期待这种机会。

这不,它来了。

这次项目的客户是一个旅游网站,本来有机会去澳洲做inception,但因为种种原因没有成行。倒不可惜,因为在项目正式开始之前,我们就忙碌着做准备工作了。说实话,我更庆幸澳洲没有成行,准备工作不失一些很有价值的东西。虽然不见得带来技术能力提升,但至少经历过了。

Web认证方法探视Git学习机器安装和环境准备用Ldap实现Web认证,JRuby,Restlet….

这个过程像是在黑暗中前行,有点担忧,但随着跟客户的沟通、以及准备工作的积极进行,目标正一点点变得清晰。原先拿到proposal时的一头雾水已经消失,心里也越来越踏实。这个过程也有一丝丝的兴奋和成就感,应用什么技术、使用什么框架、搭建怎样的环境,都成了我们可以决定的事情。

下个礼拜项目就要正式开始了,经过几周的准备工作,团队正蓄势待发。出发吧,唱着亡命之徒。

曾经我们的选择

beijing-university

记得自己曾经也很喜欢说:我不适合、我不喜欢现在干的这一行。但是当别人问我到底喜欢干什么的时候,我常常哑语。

毫不夸张地说,当年之所以选择了计算机专业,纯粹是随大流的心态。不知道现在的高中生在选择自己的大学专业时是抱着怎样的态度。回想当年,我们那些同学选择专业的原则无非如下。

1. 根据分数选专业。这是首要的原则:在分数的基础上,以不浪费一分分数的原则,尽可能上好专业。而什么是好专业?好专业就是大家觉得有前途的专业。那什么是有前途的专业?有前途就是有钱途的专业。而很明显,因为大众的趋之若鹜,那些有钱途的专业往往分数较高。当年的计算机、信息工程、电子信息、金融、外贸、生物科技等专业都是相当的热门。成绩好的同学几乎无一例外地在这些专业上分布。而真正因为自己的兴趣而选择专业的,少之又少。

2. 根据性别选专业。分数之后,开始考虑的就是自己的性别。什么性别适合什么专业,比如男生适合需要动脑的专业,女生适合语言类专业等等。高中同学选择计算机专业的大部分是男生,而选择语言类的大部分是女生,当然有些专业对性别区分不明显,比如医学(除非是护理)。进入大学之后,就更明显地印证了这个原则。理工科专业一般男女生比例都在7:1以上,而语言类专业刚好相反。

3. 根据家庭背景选专业。家庭背景不同,也会影响到你选择什么样的专业。我一高中女同学,家庭条件很好,选择了工商管理专业,不为别的,就是为了毕业后能替父亲打理企业。而大多数家庭条件一般的都基本上选择技术类专业,图个安安稳稳过日子。

当然还有更多的因素影响了我们选择什么样的专业。但是可以明显看到,在这个选择过程中起了更多作用的是社会的意愿,父母的意愿,而很少有我们自己意愿的参与。

我以为的原因有如下几种。

1. 教育体制的弊端。多年以来,我们只是被训练成了解题高手。哪有时间来培养爱好兴趣?哪有谁来关心你喜欢什么,适合什么?所以在选择专业的时候,我们大多只是拿社会上的所谓成功人士做参照系:外贸暴发户,IT新贵、企业家等等。而没法拿自己的爱好做参照系,因为我们“没有其它爱好,只知道解题”。

2. 家庭的受限。在我们这一代,特别如我家乡那种小地方,真正有学问、有文化的父母是很少的。他们基本上没有意识,也没有能力培养、指引下一代。他们更多的教导只是:要挣更多的钱。这也是为什么钱途对我们影响如此之大的原因。

3. 社会环境的影响。在整个社会都开始对金钱顶礼膜拜的时候,我们还有什么更好的选择么?

很多同学,在进入大学之后,由于突然失去了一个目标,突然少了人约束。就像脱缰的野马一样,开始肆无忌惮地堕落下去。这跟自己的约束力有关,但更跟教育体制有关。谁能忍受得住被受限自由、思想、爱好十几年呢?大家都说,这不是我喜欢的专业,但同时我们又都羡慕那些在自己的专业上取得一定成绩的人。有些人说:要是能再一次选择专业就好了。我相信再一次选择专业未必能让他喜欢,背后更多的原因是逃避的心态。

在没有经历过坚持、专注、付出之前,我们都没有能力判断,甚至没有资格说自己到底喜不喜欢自己所在的行业。

最后想说:我越来越喜欢自己的行业,享受所在的工作。

技术写作

最近写了几篇技术文章

我写技术文章的主要原因是:对此门技术感兴趣,或者需要在最近了解和掌握此门技术。

我写技术文章的主要目的是:

1. 通过写作来对此门技术加深更多的了解。通过写文章来学习技术是一个非常好的途径,因为当你要将此门技术讲解给别人听的时候,你需要对它有个更深的了解。高中老师一直劝告我们要以老师而不是学生的心态去学习,就是同一个道理。

2. 希望借此途径与共同的爱好者分享以及讨论。

3. 帮助自己记忆。我的一个毛病是容易忘记,所以需要记录下来以备后用。我已经屡次通过实践证明在自己写的文章上能更快地寻回记忆。

需要做哪些准备:当然是了解和熟悉此门技术,不管你用什么途径–阅读或者练习等等。

怎样写技术文章:除非有些非常枯燥抽象的概念,我希望把技术文章写得通俗易懂一些,并通过举一些现实的例子来解释它,使它更易被读者接受和吸收。反观之,如果不能简单明了地说清楚一个问题,说明我自己也还没有很好地掌握。

写技术文章还是挺耗时间的,一般一篇看似较短的文章,比如这篇,也花了我几个小时。不过,当完成此篇文章的时候,确实有一种满足感。有满足感,就够了。

乘时间机器,看敏捷旅程

programmer0811

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月刊。

Leary’s Rose

Leary’s Rose is a model to map the relationship between people.

For example:

people’s_instinctive_reaction => { :competitive => :withdraw, :aggressive => :defiant },

what_should_be => { :competitive => :leading, :aggressive => :helping}.

Frustrated = Growing Up

You feel frustrated after you spent 1 whole day solving a problem but still no clue yet.

You feel frustrated after you spent months to practice your skills but seems no change happened at all.

So, you give up….

But someone continues. When they look back after several years, the frustrated period is just the period of growth. Love being frustrated!

Assumptions Kill You

You want to open the window in the office when the hot air makes you uncomfortable, but at last you give up because you assumes others don’t like it.

You feel nervous when you give the presentation, because you assumes the audiences have no interest on your talk.

You miss a relationship with love, because you assumes she doesn’t have any feeling about you.

These assumptions kill you! Be assertive, you life will be completely different.

Strawood Footprint

Project:starwood

Time period:April – 12th Sep

Team members:



SVN info:
revision: 4161 (start from nearly 1800 on April for Chinese team)

Rake stats:
+———————-+——-+——-+———+———+—–+——-+
| 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

Next Page »