本文节选自电子工业出版社出版的《程序员修炼之道:通向务实的最高境界(第 2 版)》一书中的章节。
软件的熵
虽然软件开发不受绝大多数物理法则的约束,但我们无法躲避来自熵的增加的重击。熵是一个物理学术语,它定义了一个系统的“无序”总量。不幸的是,热力学法则决定了宇宙中的熵会趋向最大化。当软件中的无序化增加时,程序员会说“软件在腐烂”。有些人可能会用更乐观的术语来称呼它,即“技术债”,潜台词是说他们总有一天会偿还的——恐怕不会还了。
不过不管叫什么名字,债务和腐烂都可能失控地蔓延开。
有很多因素会导致软件腐烂。最重要的一个似乎是项目工作中的心理性状态,或者说文化。即使是一个单人团队,你的项目的心理性状态也是个非常脆弱的东西。即使有最合理的计划和最佳的人员,项目还是可能在生命周期中逐步荒废、腐烂。但也有一些项目在经历了巨大的困难、持续不断的挫折之后,成功地对抗了天然的无序化倾向,走出了困境。
是什么造成了差异?
在城市中心,有些建筑干净漂亮,而另一些则破落不堪。为什么会这样?一些犯罪和城市衰败领域的研究人员发现了一个有趣的触发机制,只需一样东西就能非常迅速地把一幢干净完好的宜居建筑变成一个破败的废弃物。
一扇破窗。
一扇破损的窗户,只要一段时间不去修理,建筑中的居民就会潜移默化地产生一种被遗弃的感觉——当权者不关心这幢建筑的感觉。然后,其他的窗户也开始损坏,居民开始乱丢废物,墙上开始出现涂鸦,建筑开始出现严重的结构性损坏。在一段看上去很短的时间内,建筑的损坏程度就足以打消业主们想修好它的期望,被遗弃的感觉最终变成了现实。为何造成这样的影响?心理学家的研究 1 表明,绝望是会传染的,就像狭窄空间中的流感病毒。无视一个明显损坏的东西,会强化这样一种观念:看来没有什么是能修好的,也没人在乎,一切都命中注定了。所有的负面情绪会在团队成员间蔓延,变成恶性循环。
提示 不要放任破窗
不要搁置“破窗”(糟糕的设计、错误的决定、低劣的代码)不去修理。每发现一个就赶紧修一个。如果没有足够的时间完全修好,那么就把它钉起来。也许你可以注释掉那些糟糕的代码,显示一行“尚未实现”的信息,或用假数据先替代一下。采取行动,预防进一步的损害发生,表明一切尽在你的掌握中。
现在我们了解了一旦窗户开始破裂,运转良好的干净系统会迅速恶化。还有一些其他因素会导致软件腐烂,我们将在别处探讨,但与其他任何因素相比,漠视会加速腐烂的过程。
你或许会觉得,没人有时间来来回回清理项目中所有的碎玻璃。如果你真这么想,劝你还是趁早多想想怎么料理这个项目的后事,或是直接离开是非之地。不要让熵赢得胜利。
先勿伤害
多年以前,Andy 认识一个土豪。他的房子富丽堂皇,屋子里摆满了无价的古董,到处陈列着精美的艺术品。有一天,一张挂毯因为离客厅壁炉太近而着火了。消防员奋勇冲进去救民于水火,当然主要是火。但是在把巨大的水管拖进屋子前,他们停了下来——尽管里面火势紧急——毅然选择先在前门和火源之间铺上垫子,因为觉得水管太脏。
他们不想弄坏地毯。
现在听起来这很偏激。消防部门的首要任务当然是灭火,何必管过程中的那些附带损害呢?但是他们在清醒地评估了形势后,出于对自己控制这场火势能力的绝对自信,还是尽力兼顾了不对财物造成不必要的毁害。这也是软件开发中应该遵循的方法:不要只是因为一些东西非常危急,就去造成附带损害。破窗一扇都嫌太多。
一扇破窗——一段设计糟糕的代码,一个让团队在整个项目周期内都必须要遵守的糟糕管理决定——就是一切衰退的开始。如果你发现自己正处在有几扇破窗的项目中,就非常容易陷入这样的想法——“反正代码所有其他部分都是一坨屎,我只是随大流而已。”项目运作在这个时间点前是不是一直良好并不重要。在最初启发“破窗理论”的实验中,一辆废弃的汽车完好无损地停放了一个星期。但是一旦有一块玻璃被打破,这辆车在几个小时内就会被扒光并翻了个底朝天。
出于同样原因,如果身处一个健康团队,你们项目的代码如此完美——编写清晰、设计优良、简洁优雅——你就会倾向于格外地小心,不把它弄糟。就像那些消防员一样,即使屋内火势熊熊(截止时限、发行日期、销售演示,等等),你也不想成为第一个弄乱它、造成附带损害的人。一定要告诉自己,“不要打破窗户。”
石头做的汤和煮熟的青蛙
有三个战场归途中的士兵饥肠辘辘。他们看到前方有一座村庄,顿时重整精神——他们觉得村民们会给口饭吃。可是当他们抵达那里时,却发现四处门窗紧闭。多年战乱下,村民们食物短缺,仅有的存粮都藏了起来。
士兵们没有气馁,他们烧了一锅水,小心翼翼地在里面放了三块石头。诧异的村民们都跑出来围观。
“这叫石头汤。”士兵们解释道。“你们在汤里只放这个?”村民们问道。“对——不过有人说如果加点胡萝卜味道会好一些……”一个村民转身跑回了家,从自己的窖藏中拎来了一筐胡萝卜。
几分钟之后,村民们又问道“这就可以了吗?”
“可以了,”士兵们说道,“加几个土豆或许更有味道。”另一个村民听到后跑开了。
在接下来的一个小时内,士兵们列出了更多食材:牛肉、韭菜、盐及各种香料,说能让汤做得更加鲜美。每次都有不同的村民跑回去取来自己的私藏。
最后,他们煮了一大锅热气腾腾的汤。士兵们把汤里的石头扔掉,和整个村子的村民一起分享了一顿美餐,这是他们所有人几个月以来吃的第一顿饱餐。
石头汤这个故事讲述了很多道理。村民被士兵骗了,士兵利用了村民的好奇心来获取食物。不过更重要的是,士兵充当了催化剂的角色,将村民们组织了起来。这样他们才能聚在一起做出他们无法单独做到的事情——一项协作的成果。最后所有人都是赢家。
从现在开始,你要考虑仿效这些士兵。
你可能处在这样一种状况下——清楚地知道需要做些什么,以及怎样去做。整个系统就在你的眼前——你知道这样做就对了。但当你为做整件事去征求意见的时候,见到的往往是推脱和茫然的眼神。人们想成立一个委员会,然后申请预算,之后事情会变得异常繁杂。每个人都会守着自己的一亩三分田。有时我们称之为“筹备期的劳累”。这个时候,就该拿出石头了——找出你合理的请求,然后不断完善。一旦有成果产出,展示给人们看,让他们大吃一惊。现在可以用上“当然了,它还可以更好,只要我们再加点……”这句话,而且要假装你并不在意。这时先坐下来,等他们开始问你要不要加些你原本想要的功能。人们都觉得,加入一个推进中的成功项目更容易一些。因为只要一窥未来,大家就能团结在一起。
提示 做推动变革的催化剂
村民们的角度
换个角度来看,石头汤的故事讲述的是一个温和渐进的骗局。因为过于将注意力集中在石头上,村民们忘却了石头外的世界,这很像我们每天陷入俗事缠身的状态。
项目进展缓慢,完全失去了控制——这是很常见的症状。大多数软件灾难都始于微不足道的小事,项目的拖延也是一天天累积而成的。系统一个特性接一个特性地偏离规范,一个接一个的补丁加到代码上,最终原始代码无影无踪。往往就是一件件小事的累积破坏了团队和士气。
提示 牢记全景
老实说,下面这件事其实我们从来都没试过。只是听“有人”说过,如果你抓住一只青蛙,把它扔进沸水中,它立刻就会跳出来。但是,如果你把青蛙放在一锅冷水中,然后缓慢地加热,青蛙就不会意识到水温在缓慢上升,直到它们被煮熟。
注意,青蛙的案例和话题 3:软件的熵讨论的破窗问题不同。破窗理论中,人们失去打败熵的斗志是因为他们觉得没其他人在乎。而青蛙仅仅只是未察觉到变化。
不要学寓言里的青蛙,永远留意着大局,持续不断地审视你身边发生的事情,而不要只专注于你个人在做的事情。
挑战
在审阅第一版的草稿时,John Lakos 提出了这样一个问题:士兵们一步步地欺骗着村民,但他们作为催化剂促成的变化对大家都好。然而,你一步步地欺骗青蛙,却是在伤害它。你在催生变化的时候,能判别是在做石头汤还是青蛙汤吗?这个决定是出于主观还是客观?不要看,马上回答,你头顶的天花板上有几盏灯?屋子里一共有几盏灯?有多少人?有没有发现什么东西有违和感,感觉它们不应该属于这里?这是一个情景感知的练习,从童子军到海豹突击队,人们都在练习这种技巧。先养成仔细观察周围环境的习惯,然后在项目中这样做。
图书简介:
评论