《大教堂与市集》(TheCathedral and the Bazaar)全文中译版

原文地址:http://article.yeeyan.org/view/Angelo/2005


《大教堂与市集》(TheCathedral and the Bazaar)全文中译版


埃里克·斯蒂芬·雷蒙(Eric Steven Raymond)【著】 刘安辙(Angelo Liu)【译】


    译者按:本书还有一章“注释”,我为了方便阅读已经拆分加入了对应章节。此外,解释一下为什么叫“全文中译版”。这是因为在我之前出现过四个版本,看时间顺序,前两个版本没有把章节译全,第三个版本没有翻译作者所写的全部注释,第四个版本没有全部翻译作者注释。所以我才用了“全文中译”这个说法。


第一章 大教堂与市集


Linux是颠覆性的,但是在五年以前(1991年)谁能想到,这些散布在世界各地的开发者仅仅依靠细细的网线相连,在业余的时间里就能开发出一套世界级的操作系统呢?


至少这让我深感意外。我在上个世纪80年代中期加入GNU,作为第一批成员,至今已经在网上发布了不少开源作品。而且一些现在被广泛使用的软件(nethack,Emacs的VC和GUD模式,xlife等等)也是我正在开发或协助开发的。1993年初我接触到Linux的时候,已经致力于Unix和开源软件开发有十年之久了,至少我那时觉得自己很在行了。


然而Linux却推翻了我的理论。当时,我已经宣扬小而专的工具、快速建立原型和演进式开发这些Unix概念好多年了。但却还是坚信对于一些重要的软件(操作系统和Emacs之类的大型工具),一旦项目进展到一定的复杂度之后就需要如同建设大教堂一样统筹管理:由个别绝世的能工巧匠细细雕琢——时机不到,公测不出。[1]


而李纳斯[2](尽早尽多的发布,托以所有可托付之事,并且能包容到泛滥之地步)的开发风格实在令人诧异。相比建造大教堂时的虔诚和肃穆,Linux社区更像是一个熙熙攘攘的市集:这里面混杂着不同流派和各种议程(Linux归档站点就是个绝佳的例证,任何人的作品都被收录其中)。如果一个统一而稳定的操作系统能从这里诞生的话,只能说是一个奇迹,一系列的奇迹。


事实是——这种风格不仅可行,而且运营良好。这给了我很深的触动。在摸索中,我不仅致力于个案,而且尝试探索为什么Linux世界不仅没有在混乱中分崩离析,反而以大教堂的建设者难以想像的速度茁壮成长。


到了1996年中,我开始略有所获。碰巧得到了一个验证这些理论的完美机会——我可以刻意的用市集的风格来运筹一个开源项目。我的确这么做了,而且成果斐然。


接下来的章节,我将讲述这个项目的故事。并借此提炼出一些对开源开发有益的格言。它们并非都始于Linux世界,但是我们却能看到它们如何在Linux世界中得以印证。如果我是对的话,它们将帮助你准确理解是什么使Linux社区成为优秀软件的源泉。如果有幸,它们还可以助您提高效率。 


译者按: 1.公测,Beta。在软件开发的测试阶段的推出的第二个版本。相比第一个内测(Alpha)版本,测试人员范围更广但是只针对漏洞进行修补,而极少对主体程序进行改动。


2.李纳斯(Linus Benedict Torvalds, 李纳斯·本尼迪克特·托瓦兹),著名黑客,Linux之父,Linux内核的发明人。著名的李纳斯定理就是以其命名。


第二章 邮件必达


自1993年起,我就在宾州西切斯特的一家提供免费网络服务的小公司CCIL(Chester County InterLink)负责技术工作。我协同创建了公司并编写了一个专用的多用户论坛程序——你可以通过telnet连接locke.ccil.org一探究竟。如今它在三十条线路上支持着近三千名用户。这使我可以每天二十四小时的通过CCIL的56K专线上网——其实,这是工作需要。


我已经惯于使用网络邮件了,但不时地登录locke检查邮件实在很烦人。我所希望的是有办法能将邮件转送到我家的机器(snark)上,并在到达的时候通知我,而且可以用本地工具进行处理。


互联网默认的邮件传输协议SMTP显然不能满足我的要求,STMP是为全时在线的机器设计的,而我家的机器不可能全天在线——况且它也没有一个固定的IP。我需要一个程序,让我能在拨号之后链接到服务器上把邮件下载到本地。我知道有这种工具存在,它们大都使用一种称为POP的简单协议,现在常用的邮件客户端软件都支持这个协议,但那时,我的邮件阅读软件并不支持它。


我在网上找到了三四个这样的POP3客户端软件。其中一个我用了一段时间,可是他明显缺少一个功能:抽取正确的邮件地址。


事情是这样的,如果locke上一个叫乔的人发给我一封邮件,我将其下载到snark上。可是在回复的时候我的邮件程序会高高兴兴的把信投寄给一个在snark上并不存在的乔。手工修正地址是件痛苦的事。


显然这是一件应该由电脑来完成的事情,可是没有一个现存的POP软件知道如何解决。这给我们上了第一课: 


1.好软件都源自解决开发者的切身之痛。


Every good work of software starts by scratching a developer's personal itch. 


或许这是众所周知的(不是有句名谚叫做“需要是发明之母”吗?),可是有那么多软件开发者为了薪水把时间都消耗在他们及不喜欢又不需要的程序上了。然而这却不会发生在Linux世界,或许这就是Linux社区产品平均质量很高的原因吧?


那么我是否应该疯狂的投入战斗,编写一套新的POP软件来和它们一较高下呢?打死都不干!相反,我仔细地检视我手中的东西,看看哪个最接近需求。因为: 


2.优秀的程序员知道要写什么,而伟大的程序员知道要改写(和重用)什么。


Good programmers know what to write. Great ones know what to rewrite (and reuse). 


我不敢自诩伟大,但是我努力效法那些伟大的程序员。他们都有一个重要的特点——建设性的懒惰,因为我们要的是结果而不是过程。从一个优质的部分接手总比你白手起家要容易的多。


以李纳斯为例,他并没有从零开始编写Linux。相反他借重了Minix的代码和理念。(Minix是一个用于个人电脑的小型类Unix操作系统)虽然Minix的全部代码最终被全部摘除或重写了,但是它毕竟为Linux充当了学步车。


出于同样的考虑,我开始寻找一个现存的有最有条理的POP程序来作为开发基础。


Unix世界共享源代码的传统让我们很容易的对它们并重新加以利用。(这也是为什么尽管GNU对Unix成见很深,却依然采用Unix为基础开发操作系统的原因)而Linux世界更是把这种传统发挥到了技术的极限。在浩如烟海的Linux开放代码中花点时间来寻找一个不错的程序,总比去别处要强的多。


加上我之前用到的,第二次的搜索让我有了九个候选对象:fetchpop、PopTart、get-mail、gwpop、pimp、pop-perl、popc、popmail和upop。首先选用的是肖恩[1]的fetchpop,我对其做了一些改动并将改写邮件地址的功能加了进去。后来他把这些改动加入到了自己的1.9版本中。


几周之后,我偶然接触到了卡尔·哈里斯的popclient代码时,问题出现了。尽管fetchpop有那么多优秀的原创功能(比如他的后台程序),但是却只能支持POP3协议,而且代码不够老练(肖恩很聪明,但是缺少经验)。卡尔的代码则更好,专业而稳固。但是却缺少很多重要的功能——那些fetchpop中的妙作(包括我加入的部分)。


是继续使用fetchpop还是改用popclinent?如果转换的话,就意味着我不得不放弃已经完成的代码来换取一个更好的开发基础。


一个实际的转换动机是去支持更多协议。POP3使用最广,却不是唯一。Fetchpop和那个竞争对手同样不支持POP2、RPOP和APOP。出于好玩,我那时已经有了在其中加入IMAP(最新设计的,最强大的POP协议)的模糊想法。


其实我还有一个更正式的理由支持我更换软件,这是我在玩Linux之前就学到的: 


3.“为舍弃而计划,无论如何,你都要这样做。”(弗雷德里克·布鲁克斯,《人月神话》第十一章,)[2]


“Plan to throw one away; you will, anyhow.” (Fred Brooks, The Mythical Man-Month, Chapter 11) 


换言之,当你开始尝试解决一个问题的之后,你通常并不知道症结所在。再次着手,或许能够游刃有余。所以想把事情做好,你得准备“至少重来一次”。【注】


好吧,(我对自己说)对fetchpop的修改就算是我的第一次吧。于是,放弃了它。


1996年6月25日,我给卡尔寄去了第一批程序补丁。才发现他对这个程序基本失去了兴趣。代码已经乏人照料很久了,小错误流连不去,有很多改动要做。我们一拍即合,由我接手。


不经意间,工作的规模扩大了。我不再只是真对一个POP客户端进行修补,而是要负责维护整个程序。一些可能会引发变革的想法在我脑海中浮现。


在鼓励代码共享的软件文化里,这样的演进方式是自然而然的。我只是将这些原理付诸实践: 


4.只要你态度正确,有趣的问题就会找上门来。


If you have the right attitude, interesting problems will find you. 


而卡尔的态度更加重要,他懂得: 


5.对一个项目失去兴趣的时候,你的最后责任就是找一个称职的接班人。


When you lose interest in a program, your last duty to it is to hand it off to a competent successor. 


为了创造一个最佳的解决方案,我和卡尔不谋而合。唯一的问题是,我是否能证明我的能力。一旦我做到了,卡尔便优雅而迅速的交托给我。希望有一天轮到我这么做的时候,我能同样的出色。 


注: 
著名的计算机学家乔·本特利(Jon Bentley)在其著作《编程珠玑》(Programing Pearls)对其做了如下评注:“如果你舍弃了一个,你还会舍弃第二个”。他的话完全正确,布鲁克斯和本特利指出:不要期望一蹴而就,以一个好主意重头来过通常要比梳理一团乱麻要好的多。 


译者按:


1.肖恩,Sean Oh,fetchpop的作者,书中出现的名称是Seung-Hong Oh。Sean是其英文名。有译者将其音译作“欧松宏”,我认为这个译音有失精当。因为Oh Seung Hong这三个拼写在韩英互译时是很常见的。与其对应的韩文大致是“오승홍”,译成汉语则大致是“吴承弘”。在没有办法联系到作者本人的情况下,为了行文不出差错,我选用了其英文名。


2.The Mythical Man-Month,Frederick P. Brooks。《人月神话》,作者弗雷德里克·布鲁克斯。计算机学家,被称作“IBM 360之父”,曾获得图灵奖和美国国家技术奖——两个计算机界举足轻重的奖项。《人月神话》是其随笔集,其在书中对繁复的工程管理做了洞见的观察。在第十一章《未雨绸缪》(Plan to Throw One Away)中其提出了舍弃型原型的概念。本文引言是强调“为舍弃而计划”,“one”用来指代一个计划或者原型,我认为不能直接译为“一个”所以用了代词“它”放宽其概念。


第三章 用户的重要性


我接手了popclient。同样重要的是,我也承继了popclient的用户基础。拥有用户是件美好的事情,他们的存在不仅仅印证了你正在供其所需,而且说明你做的还不赖。加以适当的培养,他们还能成为你的开发伙伴。


许多用户也是黑客,这是Unix传统的另一个强项,而Linux把它推向极致。因为可以获得源代码,大家的工作会更加卓有成效,这可以有效的缩短调试时间。加上一些掌声,他们会帮忙解决问题,提出建议,这总比你单枪匹马要快得多。


6.把用户当作开发伙伴,是快速改进代码和有效调试的不二法门。


Treating your users as co-developers is your least-hassle route to rapid code improvement and effective debugging. 


    这种效应的力量很容易被低估。事实上,开源世界中的人们一度完全忽视了随着用户数量的增加,该效应是如何得以大幅扩展,同时系统的复杂性并没有显著增加——直到李纳斯独具慧眼,另辟蹊径。


其实,李纳斯的睿智和最有影响的手笔并不在于他发明了Linux内核,而是创造了一种模式。有一次我当面向他表达这个见解的时候,他莞尔地说起那句口头禅:“基本上,我很懒,懒到用他人的工作换取口碑。”像狐狸一样懒惰,或许如同罗伯特·海因莱茵[1]笔下那个著名的人物一样——太懒了,才不会失败。


回顾过去,Linux方法的一个成功先例就是GNU Emacs的Lisp库和Lisp代码文档。与Emacs的C核心和其他GNU工具的大教堂模式相比,Lisp代码集则是有诸多活跃用户驱动的。创意和原型都通常要经过三四次重写才能最终成型。如同Linux,基于网络的松散协作也很频繁。


实际上,在Fetchmail之前我最成功的编程作品要数Emacs  VC(版本控制)模式了,它是我与另外三个人以互通邮件这种Linux 式合作来完成的,至今我也只见过其中一人——理查德·斯多曼(Richard Stallman,Emacs的作者,自由软件基金会的创始人)。其实它是由别人编写的一个微小粗糙的sccs.el模式演进而来的,后来成为SCCS、RCS和CVS的前台,并为Emacs提供“单击式”版本控制操作。与Emacs本身不同,VC模式的成功源于Emacs Lisp代码可以快捷的完成“释放/测试/改进”的循环。


Emacs的故事并不是惟一的。这种双级架构双层用户群(教堂形而上,市集形而下)的模式也被其他软件采用。比如MATLAB,一款用于数据分析和数据可视化的商业软件。MATLAB和其他类似产品的用户一致认为,动力、热情和创造都源自其开放部分——一个可以让各色用户都来舞刀弄棒的大校场。 


译者按:1.罗伯特·安森·海因莱茵(Robert Anson Heinlein),著名科幻作家。共获得了五次星云奖和七次雨果奖。文中提及人物出自其1973年出版的小说《Time Enough for Love》。


第四章 早发布,常发布


尽早和尽量频繁的发布是Linux开发模式的一个重要部分。包括我在内的大多数开发人员都曾一贯认为——对于一个大型工程来说这并不是个好办法。因为早期版本几乎就是问题版的同义词,而你却并不想过早地把用户的耐心消耗殆尽 。


这种信念促使人们普遍采用大教堂式的开发模式。如果首要目标是令用户尽可能少的遭遇错误,那么何不半年(或者更久)发布一次呢?这样我们就有充足的时间在各版本间努力进行调试。Emacs的C核心就是这样开发的,而Lisp库则恰恰相反——在自由软件基金会所辖以外,有很多独立的新版本或研发代码可供选择。【注1】


其中最重要的,俄亥俄州立大学的Emacs Lisp 存档,在当时就已经具有了今天Linux大型数据管理的许多精神与气质。但是我们之中少有人深思过究竟要做什么,以及这个存档的存在暴露了自由软件基金会大教堂模式的哪些问题。在1992年前后,我曾尽力想把大量的俄亥俄代码融入官方数据库,但是却在政治纠葛下半途而废了。


一年后,Linux的影响逐步扩大。显然,这要归结于一些另类不过更加有益的理念。李纳斯的开放性方针与大教堂模式大不相同。Linux的网络存档枝繁叶茂,各色发行版在坊间流传。而所有这一起都要归功于这种前所未有的核心发布模式。


以最有效的方法,李纳斯把用户视作合作伙伴:


7.早发布,常发布。并听取用户意见。


Release early. Release often. And listen to your customers.


快速发布,汲取用户反馈并不是李纳斯的创新(Unix世界历来如此),而他的创举在于将这个方法推升到了能和开发中的复杂度相匹敌的高度。早先(1991年前后)我不是没听过他那个一天之内不止一次发布核心的故事!因为他比其他任何人都辛勤的培养合作群体,促成网络协作。这是卓有成效的。


这是如何生效的?难道是源于李纳斯的天赋?


我不这么认为。无可厚非,李纳斯是个骨灰级的黑客(我们之中有几个可以从无到有创造一个企业级的操作系统内核呢?),但是Linux并不代表任何理念上的飞跃。李纳斯也不像(至少目前没有)理查德·斯多曼和詹姆斯·戈士林(NeWS和JAVA之父)那样在在设计领域天赋异禀,在我看来,他的才智更多的表现在操控和执行中。凭借着规避错误和防止陷入僵局的第六感,他能够发现解决问题的捷径。事实上,整个Linux的设计都散发出这种气质,处处体现出他质朴简洁的设计风格。


承上所述,如果快速发布和淋漓尽致的使用网络协作并非天成,而是源自李纳斯的操控天赋和对捷径的洞见。那么他究竟要把什么挥洒至极,又打算从中释放什么呢?


这样一问,答案自明。李纳斯让他的用户/黑客们不断得到激励和奖赏:激励源自参与过程中的自我实现,而奖赏则是那些持续(甚至是每天)的改进。


李纳斯直接锁定了在开发和调试中“人力—时间”绩效最大化的目标,甚至牺牲程序的稳定性以及因为难以修正的错误而流失用户也在所不惜。似乎他坚信:


8.只要有足够多的人手参与公测和开发,任何问题都会显而易见并被很快化解。


Givena large enough beta-tester and co-developer base, almost every problemwill be characterized quickly and the fix obvious to someone.


更通俗一点,就是:“足够多的眼睛,就可让所有问题浮现”,我称之为“李纳斯定律”


我最初的表述是:“(任何问题)都会被某人化解”,李纳斯却对此存有异议,他认为问题的发现和解决并不一定要由同一个人来完成,甚至可以说解决问题的通常不是发现者本人,我想这个纠正是必要的。“有人发现问题”,他说道。“其他人解决问题,而我要特别强调——发现问题才是重头戏。”在下面的章节,我们会深入探讨在调试时会发生什么。而关键是,在Linux的世界里无论发现还是修补问题都很迅速。


这就是大教堂与市集模式的区别。在修建教堂时,你所面临的错误和开发中的问题狡黠凶险、隐伏至深。哪怕几个人在几个月的时间里竭尽全力也不见得能把它们通通解决。一旦漫长的等待换来不尽如人意的产品,那么失望就在所难免了。


另一方面,站在市集的角度。你可以假设所有问题都是显而易见的——至少在上千个热情参与者的反复推敲下,它们都会变得显而易见。频繁的发布可以换取更多的修正,所以偶尔捅个大漏子也没什么大不了的!


这足可以说明问题了。如果“李纳斯定律”是错的,那么一个像Linux内核这么杂糅的东西,早该毁于一旦了。罪魁祸首自然是那些根深蒂固的错误和持续的恶性循环。换个角度,如果它是对的,也足够解释为什么Linux历来罕有错误,并且能经年累月的持续运营。


大可不必为“三个臭皮匠顶个诸葛亮”而感到诧异。多年以前,社会学家就证实:一群同样内行(或白痴)的人做出的平均预测要比其中任意一个都准确。这被称为“德尔菲效应”。[1]显然,李纳斯是把这用在操作系统调试上了。然而即使面对如同操作系统内核这样的复杂之事,“德尔菲效应”也能应对自如。【注2】


在Linux世界里,每个贡献者都是自愿参与的,这也是促成“德尔菲效应”的特别之处。早期有评论指出,这些贡献者不是随机产生的,而是要经过层层过滤。这包括:要有足够的兴趣使用软件;意图了解其运行机理;尝试自己解决遇到的问题;并且能做出实质性改进。最终产生的贡献者往往是有真材实料的家伙。


“李纳斯定律”也可以描述成“平行调试”。有时调试者可能需要和开发人员取得联系,但是他们彼此之间却不需要多少协调。故而增加开发者并不会带来成指数增长的复杂度和边际成本。


理论上,重复劳动带来的能效消耗在Linux世界一直算不上个大问题。“早发布,常发布”策略的一个结果,就是用准确及时的反馈来尽可能的减少了重复劳动。【注3】


甚至对此,布鲁克斯(《人月神话》的作者)曾做过一个非正式的论述:“一款广泛使用的软件,其维护费用是开发成本的40%以上。令人惊讶的是,其受用户影响很大,用户越多发现的错误就越多”【这是我所要强调的】


增加用户意味着增加检测程序的角度,自然发现的问题就更多。当用户参与协同开发的时候这个效应便扩大了。在纠错的时候,大家可以用不同的观察方法和分析工具,从不同视角逼近同一个问题。“德尔菲效应”便应运而生了。在这个特定的调试环境下,多样性也有助于减少重复劳动。


从开发者的角度看,更多的公测参与也许不能让最棘手的问题易于梳理。但是却能增加为解决问题找到合适人选的机会,对于这些人来说,某些问题或许称不上问题。


李纳斯还留了一手。Linux可以在出现重大缺陷的时候,为用户提供两个选择——选用上一个稳定版本或冒险体验实验版。这个策略还没有被Linux黑客普遍采用,也许他们真应该这么做。因为无论选择哪一个都能让彼此更具魅力。【注4】


注释:


1.采用市集模式的开源软件成功先例,在因特网热潮之前就出现了。所以这当然不会源自Unix和因特网传统。比如在1990年到92年初首先出现在DOS机上的info-Zip压缩工具就是一例,另外就是同样始于DOS的RBBS电子公告板系统。从1983年发展起来的强大的RBBS社团,使其至今(1999年中)都充满活力——无论其间网络邮件和文件共享技术发生了多么翻天覆地的变化。如果说info-Zip社团还或多或少的使用了网络邮件的话,那么RBBS开发则纯粹的依托于一个以TCP/IP为基础形成的在线社团。


2.对于扫清操作系统开发的复杂障碍,公开平等的审视是大有助益的,其实,这算不上是个新观点。在1956年考巴托和维萨斯基共同设计了一个名为Multics的早期分时操作系统。[2]他们希望当Multics运行良好并满足下面两个条件的时候能得以发布:首先,它要经受的起来自用户无偿地公开审视和批评。其次,当自身越来越复杂的时候,其有责任对未来的开发者做出贡献,以便令他们可以尽己所能开发出内核明晰的操作系统。换言之,就是有责任公开自己的最基础版本。


3.对于在开源开发中,为何重复劳动算不上个大问题的原因,约翰·哈斯勒(John Hasler)做过一个有趣的解释。他建议我命名为哈斯勒定律:重复劳动开销的增长趋向低于由开发团队扩大带来的指数式成本增长。也就是说,开发团队扩大所带来计划和管理成本增速要远高于重复做功的开销。


这与布鲁克斯定律并不冲突,总体而言,抚平复杂度和纠正错误的成本是与开发团队规模成平方正比增长的,然而重复做功带来的开销则是其中同比增速缓慢的一个独特环节。我们不难为此找到一个看似可信的原因:以一个既定的目标开始工作比让一群自主的开发者达成一致要简单的多,而且可以预防重复做功。但是却不能有效的阻止开发陷入无法预期的恶性循环,最终导致整个系统置身错误之中。


将李纳斯定律和哈斯勒定律结合起来,我们不难找到三种软件工程的对应模式:对于开发者不超过三人的小工程,无需领导和预设管理结构。对于中型工程,采用传统的管理模式成本则相对较低。并且可以有效的防止重复劳动,错误追踪,并且能很快的发现详细资料是否有遗漏,从而确保万无一失。


在此之上,李纳斯定律和哈斯勒定律共同说明了:对于大型工程,传统管理模式带来的问题和成本增幅,远超过预期的重复劳动的开销。而这种调动大家参与所带来的微小开销并不是一个结构上的缺陷,相反(我们看到)这能比传统方法更有力的保证错误和细节无一遗漏。在大型工程中,应用这两则定律可以让那些传统模式下的本息(沉默成本和边际成本——译者按)趋近于零。


4. Linux拆分稳定版和实验版的作法,除了分担风险之外还有一个作用——干掉发布期限。实际上,一旦程让序员同时面对刻版的功能列表和该死发布时间,软件的质量就会大打折扣。这是研发中的一个重要问题。感谢来自哈佛商学院的马可·伊恩斯蒂(Marco Iansiti)和艾伦·麦科马克(Alan MacCormack)让我明白了一个道理——放松二者任意一个,都可以让工作进程更加有效。


一个做法就是制定发布日期,但让功能列表可以变通调整。也就是说,在发布时允许舍弃部分功能。这是稳定版内核开发的基本策略;艾伦·考克斯(Alan Cox,稳定版内核的维护者)定期发布稳定版,但是不承诺何时解决某个问题或者何时添加某个实验版的新功能。


另一个做法则是,锁定开发列表但不制定发布时间。这是实验版内核开发的基本策略。我们称之为:“做完再叫醒我(wake me up when it's done)策略”。达·马可(De Marco)和利斯特(Lister)的研究表明这不仅可以提高软件质量,而且平均而言,它比任何“激进”或“保守”的策略都节省研发时间。


2000年初,我开始怀疑自己在前作(指本书的前期版本——译者按)中严重低估了这种反发布时间(做完再叫醒我)策略对于开源社区的生产力以及质量的重要性。1999年GNOME仓促1.0版的教训表明:即使是开源项目,为了赶进度而草率发布,也会严重影响软件质量。


有充分的理由可以表明:开发过程的透明化、“做完在叫醒我”的策略以及开发者自主选择研发对象的方法。是影响开源项目质量的三个同等重要的作用力。


译者按:


1.德尔菲效应, Delphi effect。德尔菲(Delphi)是希腊古都,宏伟的阿波罗(Apollo,太阳神)神殿便座落于此。相传阿波罗经常在此宣布神谕,而在决断之前会广泛争取意见。故而这里成为古希腊先哲聚集论道的场所。20世纪中期,美国军方和兰德(RAND)公司合作开展国防项目——“德尔菲项目”。顾名思义,其着重采用广泛收集观点意见的方法,从而产生了“德尔非法”(Delphi method)。日后“德尔菲法”被广泛应用于工程和管理领域,形成了“立论-驳论-综述”的三段式方法。


本书中的“德尔菲效应”则是作者的创造。德尔菲法强调广泛征集专家的建议。而作者则并不认为必须专家参与,而且参与者的广泛度和涵盖面都远超过德尔菲法。德尔菲法是一种方法,众多专家参与,是其前提条件。而德尔菲效应则是强调一种广泛平等参与所带来的结果。


简而言之,我认为这就是我们中国人说的“兼听则明,偏信则暗”。


2.考巴托:费尔南多·考巴托(Fernando J. Corbató)杰出的计算机学家,1990年图灵奖的得主。


维萨斯基:维克托·A·维萨斯基(Victor A. Vyssotsky)著名数学家、计算机学家。


二人曾共同设计了Multics的内核,在该计划停止之后,由贝尔实验室的工程师以C语言为基础借此开发而成了Unix。


第五章 要多少只眼来驯服复杂


从 宏观上,可以说市集风格大大加速了调试和代码演进,但是如果想从微观(开发者和测试者日复一日的工作中)上,准确理解这是如何和怎样起到作用的,却又是另 一回事了。在本章中(作于本书初版后三年,采纳了阅读本书,并身体力行的开发人员的意见),我们将关注其背后的机理,对于技术不感兴趣的读者可以安心的跳 到下一章。


理解问题的一个关键在于认清如下的重要事实,那就是那些对源代码知之甚少的用户所提交的错误报告通常派不上大用场。因为他们一般只看到表面症状。在提交错误报告的时候,习惯从自身环境出发,这样(一)会忽视重要的背景数据,(二)通常会遗漏重现错误的关键步骤。


更深层的问题是,开发者和测试者的思维模式不同。测试者是由表及里的看问题,而开发者则是自内而外。在封闭源代码的开发环境里,他们被各自的角色羁绊,往往各说各话而且认为对方很难沟通。


开源开发打破了这种束缚。基于源代码,测试者和开发者可以很容易建立一个统一的模型,并借此有效沟通。仅仅描述表面症状的问题报告和深入源代码基础抽象模型的报告,对于开发者而言作用是截然不同的。


在代码层,即使一个不完整的提示性错误描述,都可以让它们在大多数情况下得以修正。比如当某个公测人员指出:“在某某行存在边界问题”,甚至只是说出“在某某条件下,变量溢出”的时候。通常进行一次对于问题代码的快速扫描就足以锁定成因,加以修复了。


所以,如果公测人员和核心开发者都对代码心中有数,那么沟通和协作就很容易展开。这就意味着节省核心开发者的时间,即使协作者众多。


另 一个节约开发者时间的方法源自典型的开源通讯结构。我在文中使用了“核心开发者”一词,这有别于“项目核心”和“项目外延”。(“项目核心”一般很小;通 常包括一到三个核心开发者,当然如果只有一人也不足为怪;“项目外延”则通常包括数以百计的“公测人员”和“贡献者”)


正如布鲁克斯定律所言传统软件开发结构下的根本问题是:“为已经延期的项目增添人手会让它拖的更久。”通俗的讲,布鲁克斯定律昭示了:项目的复杂度和通讯成本会以开发人数为基础,呈现平方指数的增长态势,而绩效则仅能直线上升。


经验证实,错误大多集中在(不同人编写的)代码的接口处,而沟通/协调成本则会随着人员交流渠道的增加而增加,这就是布鲁克斯定律建立的基础。然而问题也会随着开发者沟通渠道的增多而增加,后者恰好等于开发人数的平方。(更确切地说,是遵循N*(N-1)/2公式,其中N代表开发者人数)


布 鲁克斯定律(对于开发团队过大所导致的令人担忧的结果)的分析是基于一个潜在假设的:即项目必须采用全向连通的通讯结构,也就是说每个人都能与其他任何人 取得联系。然而在开源项目中,外延开发是可以分离的平行子环节,彼此关联甚少。代码变动和错误报告都流经项目的核心团队,只有在那里我们才需要担负“布鲁 克斯式”的管理成本。


代码层的错误报告对开发大有助益的原因还有很多,然而它们都围绕着一个事实。那就是:同一个错误在不同的操作习惯和环境下会表现出不同的症状。这类问题通常复杂隐蔽,难以重现和静态捕捉,它们正是造成软件长期问题的祸根。(比如动态内存管理出错或者随机窗口中断的影响)


一则源自测试者的(源代码层)试探性描述(例如“我觉得1250行 附近像是有个信号处理窗口”或者“你在哪把缓存清零了?”),就可能会成为“当局者迷”的开发者同时解决六七个不同表象问题的关键线索。我们往往很难为五 花八门的症状找到对应的错误,但是只要你发布的够频繁就无需为此担忧。因为其他协作者会很快的去查看自己提交的问题是否已经被修正了。多数情况下,源代码 层的错误报告可以让许多问题没有经过特定修补就消失殆尽。


对 于复杂多变的错误,从表面症状探索其成因的途径通常也很多。而对开发者和测试者而言,走哪条路则取决于他们自身所在的环境,而且也可能因为时间而产生一些 无法预期的变化。实际上,开发者和测试者在为症状寻找病因的时候,都可以看作是对程序某部分运行状态的“半随机”取样。错误越是隐蔽复杂,取样对症的成功 率也就越低。


对于简单易于重现的错误,重音应该落在“半”而不是“随机”上;此时,调试技巧和对代码以及其结构的熟识能派上大用场。然而对于复杂的错误,重音则转向“随机”。因为在这种情况下,众人多管齐下比少数人循序渐进要强的多——即使这“少数人”的平均水品很高。


如 果挖掘错误的途径不一,很难凭表面现象预测的话,并行纠错的效果就很明显了。一个循序渐进的开发者可能一开始就选择了一条复杂的途径,当然他也可能一开始 就选择到了简单的途径。让我们换一个角度,如果软件发布的够及时,那么众人就可以多管齐下。他们其中很可能有人立即就能找到一条快捷的途径,所以在极短的 时间里就能修复问题。项目的维护人员看到改进,于是发布新版本。这样,那些通过其他困难途径探索同一个错误成因的人就可以在浪费掉更多时间之前停下来。 【注1】 


注释:


1. 根 据为我提供不同难易追踪途径的读者的推测,这种对多表象错误的追踪的复杂度呈“指数”分布(我理解为高斯或者泊松分布,而且这听上去很有道理)。要是能通 过实证绘出类似分布曲线的话,绝对很有价值。假如其与等概率分布平行线大相径庭,那么即使独自开发也应该努力效仿市集模式。也就是限定追踪问题的成因的时 间,如果在限定时间内没有结果,那么就跳转到下一问题。坚持有时不见得是件好事……


第六章 花香何曾随名去?


在研究了李纳斯的作法,并得到他何以成功的理论之后。我决定在我的新项目中(当然没有Linux那么复杂和雄心勃勃)有意地尝试这些理论。


但是我首先要对popclient做大幅的重写和简化。卡尔·哈里斯的代码很扎实,但是却如同大多C程序设计师一样,有种不必要的繁琐。他把代码置于核心,而数据结构作为其支撑。结果代码很漂亮,而数据结构就很特别了,甚至可以说很缭乱了。(至少就LISP老手的标准而言是这样的)


除了改进代码和数据结构,我的重写还有另一层目的,就是要把它演进成一个我完全理解的东西。因为要是你不能对程序了如指掌,维护起来可就不好玩了。


在最初的一个月里,我只是遵循卡尔的设计理念。我所作的第一个重要改变是加入了对IMAP的支持。做法是:把原来的协议支持部分改写成一个通用驱动和三个可调用的方发表(分别针对POP2、POP3和IMAP)。这些变动都阐明了一个程序员需要铭记在心的通用原则(特别是对于像C这样本身不支持动态类型的语言): 


9.精巧的数据结构即使搭配笨拙的程序代码,也比精巧代码加笨拙结构的组合要强得多。


Smart data structures and dumb code works a lot better than the other way around. 


布鲁克斯在《人月神话》的第九章中写道:“只给我看你的工作流程却隐藏表单,我将仍然一头雾水。但是如果你给我展示表单,或许不需要流程图,就能柳暗花明了。”[1]哪怕历经三十年的文化和术语变迁,这个观点依旧正确。


这时(1996年9月初,开工后大约六周),我开始考虑要给软件换个名字了。因为毕竟它已经不仅仅是个POP客户端了。但是我在犹豫,因为设计上没有什么新突破,我的popclient需要独具一格。


当popclient学会如何将收取到的邮件再通过本机SMTP端转发的时候,这一切迅速改变了。这个容后再表。首先,我之前说过要在开发过程中验证李纳斯成功的理论,那么(你也会问)我是怎么做到的呢?


我早发布,常发布(从未低于十天一次,在高强度的开发周期则每天一次)。
我把每个曾和我讨论fetchmail的人都列入公测名单。
每当新版本发布,我都会不厌其烦的给公测名单里的每个人寄送一份,并鼓励其参与。
我听取公测人员的意见,在设计上征求他们的看法。并且当他们寄回补丁和反馈的时候,给予鼓励。
这些简单的方法立竿见影。在项目一开始,我就收到了很多能让大多数程序员垂涎三尺的高质量错误报告,而且经常还附带不错的修补方法。我还收到过深刻的评论、支持者的来信,高明的功能建议。这一切都证明: 


10.如果你把公测参与者作为最宝贵的资源来对待,那么他们就会成为你最宝贵的资源。


If you treat your beta-testers as if they're your most valuable resource, they will respond by becoming your most valuable resource. 


这个项目庞大的公测名单(我称之为“fetchmail之友”)成为衡量fetchmail成功的重要标准。在我最后一次修订本书(2000年11月)的时候,已经有了287个成员,而且每周还要增加两到三名。


实际上,在1997年5月下旬我改写本书的时候发现,发现出于一个有趣的原因,当人数逼近300峰值时就会开始流失成员。一些人要求我把他们从名单中去掉,因为fetchmail对他们而言已经近乎完美了,所以他们不再需要收到通讯了。或许对于一个成熟的市集型项目,这是其正常生命周期的一部分吧。 


译者按:


题解:本章原题为“When Is a Rose Not a Rose?”,化典自莎士比亚名句“A Rose, by any other name, would smell as sweet.”(即使玫瑰不再叫做玫瑰,其依然香醇如故),作者这里的反问是说,即使软件的名字变了但是其优良的质量不会变。至于其名称和质量究竟变与没变,将在下文见分晓。


1.其中原文是:“Show me your flowchart and conceal your tables, and I shall continue to be mystified. Show me your tables, and I won't usually need your flowchart; it'll be obvious.”在计算机领域flowchart指流程、运作机制、发生过程、在此处可以理解为程序代码。而table则指数据的有序排列,这里可以理解为数据结构。《人月神话》是软件工程方法概论;而且布鲁克斯在写作的时候,现在的计算机词汇还没有产生,比如数据结构(data structures)的说法大致是与其写作同期(1968年)才开始被广泛使用的。所以作者说“历经三十年的文化和术语变迁”。


第七章 Popclient变成了Fetchmail


项目的真正转折点来自一份哈利·豪切斯的草拟程序,通过它我们可以将邮件转发至客户机的SMTP端。几乎在收到程序的同时,我就意识到,这个功能会让其他的邮件传送模式都成为历史。


我曾用几周的时间摆弄fetchmail,当时总觉得虽然界面还能用但是却不够漂亮,到处是用处不大的选项。“将收取到的邮件归档”或者“标准输出”选项尤其让人心烦,可我却说不出个所以然来。


(如果你对网络邮件的技术细节不感兴趣,那么就可以安心的略过下面两段。)


当我考虑加入SMTP转发的时候,才发现popclient包揽了太多的事情。它身兼两职——既是一个邮件传输工具(MTA)又是一个本地投寄工具(MDA)。但是如果有了SMTP转发功能,它就可以摆脱MDA的工作。像sendmail一样专注于MTA并把邮件的本地投寄工作交给其他软件。


几乎每个支持TCP/IP的平台都预留了25号端口,那么何必去折腾复杂的代理设置或者“添加-锁定”本地邮箱呢?特别是,这样可以保证收到的邮件看上去就和一封直接投寄的普通SMTP邮件一样。这才是我们想要的!


(承前段……)


就算你没看懂前面的技术细节,这里还是有几条值得学习的重要经验。首先,这个SMTP的创意是我效法李纳斯的最大收获。用户提供好的创意——而我要做的仅仅是理解它的含义。 


11.自主创意很好,能认可源自用户的点子也不错。有时借笔生花更具成效。


The next best thing to having good ideas is recognizing good ideas from your users. Sometimes the latter is better. 


有趣的是,你会很快发现,即使你谦卑地坦陈别人为此做出多大的贡献,外界也不会这么看。大多数人认为是你创造了一切,而你只是为自己的天赋表示出适当的谦虚。李纳斯就是个生动的例子!


(1997年8月,我在第一届Perl大会上发言时,杰出的黑客拉里·沃尔正坐在前排。当我讲到上面那句的时候,他醍醐灌顶般的叫出声来:“说下去,说下去,哥们!”引得哄堂大笑。因为大家知道,这一点对于Perl的发明人也不例外。)[1]


在以同样的精神将项目运营了几周后,我开始收到类似的褒奖。不仅来自我的用户,而且来自对此有所耳闻的人。其中一些邮件被我收藏起来了,万一哪天我开始怀疑我生命的意义了,就翻出来看看:-)。 


12.通常,当你确信自己在解决一个错误问题的时候,会激发最具突破和创造力的方案。


Often, the most striking and innovative solutions come from realizing that your concept of the problem was wrong. 


把popclient开发成一个组合软件(作为MTA兼MDA,让他支持五花八门的本地投寄模式),实际上等于在尝试解决一个错误的问题。fetchmail应该被重新设计为一个纯粹的MTA,作为常规SMTP邮件传输路径的一部分。


当你在开发中碰壁(绞尽脑汁也无法做出下一个补丁)的时候,通常应该问问自己:“我是否找到了正确的答案?”或者“我是不是找对了问题?”。也许有些问题需要重新定义。


好,我这就重新定义我的问题。显然,正确的做法是:(1)在主驱动中加入SMTP转发支持,(2)把它设置为默认模式,(3)最后,抛弃所有其他传输模式,尤其是“本地归档”和“标准输出”两项。


第三步让我踌躇颇久,因为担心会流失依赖此模式的老用户。理论上,他们可以立即使用forward格式文件或者非sendmail的类似功能来达到同样的效果。但实践中,这种转变大费周章。


一旦真这么做了,我发现好处非明显。驱动代码中的症结就此消失,配置选项也大大简化了。再不需要围着系统的MDA和用户的本机邮箱打转了,也不需要为操作系统是否支持归档文件锁定而伤脑筋了。


而且,惟一可能出现邮件丢失的情况也没有了。过去,假设你指定了邮件归档路径,而恰好磁盘满了话,你的邮件就没了。而这在SMTP转发中不会出现。因为除非传送完成或至少已经暂入缓存了,不然SMTP接收端不会发送确认信号。


同时,性能也提高了(尽管这不是你运行一次就能感觉到的)。另外值得一提的是,用户手册也简化了许多。


 日后,为了应付一些来自动态SLIP[2]的纠葛,我又不得不重新加入了可由用户制定MDA功能。但是做起来简单多了。


这说明了什么?只要不损失效率,就不要对丢弃一些功能而举棋不定。圣-埃克苏佩里[3](当他不写作经典儿童书籍的时候,是一个飞行员兼飞机设计师)曾说过: 


13.“完美(的设计)意味着没有东西可以再被加入,而是没有东西可以移除”


`“Perfection (in design) is achieved not when there is nothing more to add, but rather when there is nothing more to take away.” 


当代码变得高效又简洁的时候,就可以说是走上正轨了。在这个过程中,fetchmail有了自己的特设,脱离了前代的popclient。


到了该换名字的时候了,新的设计和老的popclient相比,更像是sendmail的搭档。二者都是MTA,不同的是sendmail是向外投寄,而新的popclient是接收转发。所以,开工两个月之后,我把它更名为fetchmail。


在这个将SMTP转发加入fetchmail的故事中,有一则普遍的经验。那就是不仅调试可以平行展开,开发和(也许这很令人吃惊)探索设计空间同样也可以。当采用快速短周期开发模式的时候,开发很可能成为针对原有的冗余设计或开发观念的一个特殊“调试-修补”环节。


即使在更高层次的设计中,能有许多协作开发者围绕着你的产品设计空间随机游走也是很有价值的。试想一下,一滩水是如何找到排水口的,或更贴切一点,一群蚂蚁是如何找到食物的:实际上就是在分散搜索之后,以一个可延伸的通讯机制加以协调。这很管用,就像哈利·豪切斯和我一样,一个同行之人很可能在你身边开启宝藏,而你只不过是太过专著才一叶障目罢了。 


译者按:


1.拉里·沃尔 :Larry Wall,著名黑客,第一届自由软件奖得主。也是Perl语言的发明人,所以作者说“对……也不例外”。


2.SLIP:Serial Line Internet Protocol,即串行线路IP协议,早期的一中IP封包协议,目前基本已不再使用。


3.圣-埃克苏佩里:安托万·玛丽·罗杰·德·圣-埃克苏佩里(Antoine Marie Roger de Saint-Exupéry),法国作家、飞行员。著作颇丰,1943年出版的《小王子》令他誉满全球。


第八章 Fetchmail成熟了


现在有了一个简洁新颖的设计,我确信代码运行稳定,因为我每天都在用,公测名单也枝繁叶茂。我逐渐发现,我不再只是研发一个可能只有少数人才会用到的琐碎的个人软件了。而是在主持一个所有使用SLIP/PPP邮件接口的Unix用户都切实需要的软件。


凭借SMTP转发功能,fetchmail把竞争对手远远的甩在了后面,成了一个潜在的“领域杀手”。一个在同领域鹤立鸡群的杀手,它让对手们不但被抛弃而且被遗忘。


这种结果是可遇而不可求的。一个卓有建树的设计构想会把你顺理成章,甚至命中注定地推向成功。而找到这类构想的方法无非是拥有很多值得尝试的创意——或者能用工程的眼光把其他人的创意发挥到令原作者都难以想像的境地。


安迪·塔能鲍姆[1]首先为IBM PC机开发了一个简单的原生Unix系统,他的本意是把它作为一个教学工具(他称之为Minix)。李纳斯则把Minix的概念推臻至安迪想像不到的境地,让它成了这个奇妙的玩意。类似的(只是规模小些),我从卡尔·哈里斯和哈利·豪切斯那里借得创意并把它们深化。我们都不是“原创”——那种人们浪漫想像中的天才。话说回来,大多数科学、工程和软件的成果都不是来自原创天才,恰恰相反,是锐意进取铸就了神话。


这两个项目(指Linux和fetchmail——译者按)都成果斐然——事实上,这正是每个黑客毕生求索的成功!这同样意味着我不得不加高要求自己的标准。为了让fetchmail达到预期的目标,我不仅要为自己编程,还要额外地加入别人需要的功能。与此同时,还必须保证程序的简洁和健硕。


意识到这点之后,我加入的第一个也是至关重要的功能就是“集体收发”——从一组用户的邮箱中收取邮件,之后在分发给不同的收件人。


我添加集体收发功能不仅是因为很多用户吵着要用,更主要的是我觉得通过这个方法可以迫使我更全面的处理地址问题,从而摆脱单信投寄中的缺陷。结果得我所愿。正确地完成RFC822[2]地址解析耗费了我很长时间,并不是因为它的某一部分很难,而是它牵扯了一堆相互关联的烦人细节。


添加集体收发成为了一项杰出的设计决策,只因为: 


14.任何工具都应该起到预期的作用,而一个真正杰出的工具会带来出乎意料的用途。


Any tool should be useful in the expected way, but a truly great tool lends itself to uses you never expected. 


加入集体收发的一个出乎意料的用途是让通过网络相连的客户端可以保存邮件列表和别名扩展。也就是说,通过ISP上网的个人用户不需要持续访问ISP的别名文件就可以管理邮件列表了。


我的公测人员要求加入的另一个重要功能是支持8位的MIME(Multipurpose Internet Mail Extensions,多用途的网际邮件扩充协议)操作。这很容易办到,因为我之前就很小心的保留了对代码的8位兼容性(就是,没有强迫ASCII字符集中未曾用到的第8比特位去携带程序信息)。这并不是因为我有先见之明,而是遵循了另一个原则:


15.在写任何网关软件的时候,都该花点功夫尽可能不去干扰数据流——除非用户强迫你,否则永远不要抛弃任何信息!


When writing gateway software of any kind, take pains to disturb the data stream as little as possible—and never throw away information unless the recipient forces you to! 


假设我不曾遵循这个原则,那么加入8位MIME支持就会很困难而且毛病多多。事实上,我现在做的只是读一下MIME标准(RFC1652)[3],然后加入一条小小的标头生成规则。


一些欧洲用户请求我加入了一个选项,来限制每次连接可下载的邮件数目(这样他们可以节流昂贵的电话上网费)。我曾长时间抵触这种做法,就算现在也不是心甘情愿。但是如果你是在为外界编写程序,那么你就必须听从你的客户——即使他们不付钱也应如此。 


译者按:


1.安迪·塔能鲍姆:安德鲁·斯图尔特·塔能鲍姆(Andrew Stuart Tanenbaum)昵称安迪(Andy)美国计算机学家,现定居荷兰。


2.RFC822:Standard for the format of ARPA Internet text messages,标准ARPA 互联网文本消息格式。


3.SMTP Service Extension for 8bit-MIMEtransport,SMTP 8bit-MIME传输服务扩展。


第九章 源自Fetchmail的更多经验


在我们回到广义的软件工程问题之前,还有几条fetchmail开发中的独特细节需要深思。非技术性的读者可以安心跳过本章。


rc(fetchmail用户配置)文件语法中包含了一些完全不需解析的,可选的“噪音”关键词。与传统“关键词-对应值”匹配关系相比,它们所带来的趋近于英语语法的配置文件更具可读性。


这源自一个深夜的实验,当时我注意到rc文件的配置命令非常像一门微型指令语言。(这也是我把关键字“server”改成“poll”的原因)[1]


在我看来,努力使这个微型指令语言更像英语可以让其更便于使用。现在我虽然支持“让它成为一门语言(make it a language)”的设计流派(诸如Emacs、HTML和很多数据库引擎那样),但是并不热衷于“类英语”的语法。


传统上,程序员们倾向选用简洁紧凑、完全没有冗余的语法。这是计算资源昂贵时期的文化遗留,以致解析过程必须尽可能的简洁廉价。所以如果采用像英语这样有50%冗余的语法建模,在当时显然是很不合时宜的。


这并不是我通常避免使用“类英语”语法的原因。我在这里提及就是为了打破这种观点。有了更廉价的缓存和处理器,简洁就没有必要称为最终的追求了。现在一门语言的人性化远比降低计算成本要重要。


然而,我们仍然有要谨慎为之的原因。其一就是解析过程的复杂度带来的成本——你总不希望这个成本上升到足以滋养错误和迷惑用户吧?另外,让一门语法趋近英语的作法,通常会令其所谓的“英语”走形。以至于对自然语言的表面的模仿会导致如同传统语法一般的混乱。(你可以在很多号称“第四代”的和商业数据库查询语言中看到这种恶果)


Fetchmail的控制语法之所以能避免这些问题,是因为它的语言空间极为有限。它离一门多用途的语言还差得远呢;其所描述的问题也很简单。所以大可不担心穿梭于微小的英语子集和实际控制语言会造成什么迷惑。我觉得这里有一则可以推而广之的经验: 


16.当你的语言还远不足以达到图灵完备的时候,不妨为语法蘸上一层“糖衣”。[2]


When your language is nowhere near Turing-complete, syntactic sugar can be your friend. 


另一则经验是有关隐藏的安全性的。一些用户要求我改写软件,以便能对rc文件加密。这样入侵者就不会在无意间看到它们。


我没有照做,因为这并不会带来实际的保护。因为只要有人能获得你rc文件的使用权,他就能和你一样运行fetchmail查看邮件——如果真的想要你的密码,他就可以从fetchmail代码中剥离出必要的解码器。


言而总之,在rc文件中注入密码只是给那些没有深入思考的人一种安全的假象。进而,我们得出通用的规则: 


17.安全系统的效用只取决于对秘密的保护,谨防伪安全。[3]


A security system is only as secure as its secret. Beware of pseudo-secrets. 


译者按:


1.这个关键字后面对应的是邮件服务器名称。计算机中,“Poll”是动词“轮询”的意思,也就是依次向服务器发送报文,收取邮件。而“Server”是名词“服务器”。显然使用“Poll”更符合英语语法。


2.图灵完备:又称图灵完备性。如果一门语言达到“令一切可计算的问题都能计算”的程度就可以说其达到了图灵完备或说具有图灵完备性。


3.“秘密”是指所要隐藏的标的;“安全系统”是指保护这个标的不泄露的手段;“伪安全”是指将标的写入手段的做法。让我们以fetchmail为例,“秘密”就是要保护rc文件,“安全系统”就是密码,把密码写入rc文件显然就是伪安全。


第十章 市集风格的先决条件


本文的早期审阅人和测试者不断地希望了解成功市集风格的先决条件,这包括项目负责人的资质和着手建立协作开发社区时代码的开放状况。


很明显,市集风格不能帮你从零开始编程。【注】你可以利用市集风格来测试、调试、改进代码,但是用这种风格来孕育一个项目会很困难的。李纳斯没有这样试过,我也没有。你初建的社区至少需要一个可以运行和测试的东西。


一旦你着手组建团队,就需要给出一个可行的承诺。你的程序并非必须运行良好,它可以是粗糙的、遍布瑕疵的、不完善的、也可以是缺少说明文件的。但是必须满足(1)它能运行;(2)能让潜在的协作开发者相信在不久的将来它能变得精良。


Linux和fetchmail都是在有了健硕,诱人的基础设计之后才推向公开的。我所提到的市集模式观察者们认为这是至关重要的。进而得出结论:一个睿智并且具备高超设计才能的领导是必不可少的。


但是李纳斯是从Unix出获得的设计,而我则是从早期的popclient(尽管日后改动很大,但是还无法和Linux相提并论)。那么,一个市集风格的领导者/主持人当真需要天赋异禀吗?或者他们只是四两拨千斤的动用了他人的创见?


在我看来一个项目的主持人是否能够做出足以彪炳的设计并不很关键。而至关重要的是,他是否可以从他人的创意中慧眼识英。


Linux和fetchmail都印证了这个观点。李纳斯(如同前文描述的那样),尽管不是一个惊世的原创设计者,但是却展现了识别优秀设计并整合成为Linux内核的不凡才能。我也曾描述了fetchmail中最强大独到的功能(SMTP转发)是如何源自他人的。


本文的早期读者捧我的场说我之所以容易低估市集项目中原创因素的价值,是因为我本身不缺乏创意灵感,所以就习以为常了。这番评论或许却有见地,因为(与编码和调试相比)设计确实是我的强项。


但是问题是,在软件设计中展现聪明和原创力会养成一种习惯——当你需要保持设计稳健和简洁的时候,会不自知把它们弄得有趣而复杂。我曾经因此搞砸过项目,所以在fetchmail的开发中我要避免重蹈覆辙。


所以我坚信fetchmail项目的成功应部分归因为我克制了自己的自作聪明;这(至少能够)反驳“原创设计制约市集模式成败”的观点。回头看Linux,假设李纳斯在开发操作系统核心时力主原创的话,我们现在还能见到如此稳健成功的内核吗?


一定的设计和编码技能是必须的。但是我想,任何一个深思熟虑准备试水市集项目的人都远远超出了这个底线。开源社区内部的声望机制给人们一种微妙的压力,从而大家不会去发起一些自己无力支撑的项目。目前看来,这行之有效。


我认为还有一种与软件开发无关的技能,却在市集项目中与优秀设计同等重要——甚至更胜一筹。那就是一个市集项目的主持人或领导者必须具备优秀的人际交流技能。


显而易见,要创建一个开发社区,你需要招募人手,让大家对你所做的感兴趣,并让大家对工作乐此不疲。为了达成这个目标,技术上的磨合必不可少,但却远不是故事的全部。与大家的人际融合也至关重要。


李纳斯平易近人,招人喜欢并让大家乐于帮助他——这并非偶然。我活波外向,喜欢群体工作,并且带有一些插科打诨的言谈和性情——这也绝非巧合。为了运营一个市集项目,哪怕是一点点人格魅力都对你大有助益!


 注:


有关市集风格是否可以帮你从零开始构建一个项目的另一个争论是——其是否能够促成真正意义上的创新。有人声称,由于缺少强有力的领导。市集风格只能在工程学前沿克隆和演进已有创新,却无法孕育新知。这种垢弊极可能源自“万圣节文件”——两份微软内部旨在发难的开源现象备忘录。其作者认为,Linux不过是个拾人牙慧的类Unix系统,“(一旦这个计划具有了同等的领先水平)管理开销就必然变得异常庞大。”


这个观点和事实大相径庭,乃至文件作者后来自己也指出:“通常……创新首先出现在Linux上,其后才被推广/整合到其他平台。”


对我们而言,即使把上文中的“Linux”换成“开源软件”也算不得什么新鲜事。回顾历史,开源社区并没有拾人牙慧的开发出Emacs、万维网和因特网,同样也未曾担负过庞大的管理成本。现在开源项目的不断创新给我们提供了前所未有的施展空间。比如GNOME项目(信手拈来一例),已经达到了图形用户界面领域的顶尖水品。其复杂程度吸引了Linux社区外为数可观的商业关注。类似的例子不胜枚举,你可以抽空访问一下Freshmeat.net,一看便知。


其论断中还有一个本质的错误,即假定大教堂模式(或市集模式,亦或其他任何管理结构)可以顺理成章的产生革新。这是一派胡言。群体没有洞见创新的眼光——对此,市集模式中志愿组合的团队也往往无济于事。更不用说那些要为自己生计下注的社团委员会成员了。创新源自个体。其周围社会机制的最有效激励就是做出适当的回应——去培养、奖励、鞭策他们,而不是排挤。


一改过去“孤单发明家”的套路,有人会把这种创新方式描述的颇具浪漫色彩,然而事实远非如此;我并非断言团队无法再像过去那样在开发中创造突破;事实上,我们在平行开发中学到,对于高质量的产品,团队协作是必不可少的。但是我必须指出任何团队的组建都是源于某人的创想(这也是必要的火花)。无论大教堂、市集、还是其他模式都可以抓住这稍纵即逝的火花,并将它引燃。不过,它们都不能在有需要的时候就立即擦然火花。


所以说,(软件或其他领域)革新的根本问题是:首先,如何培养那么多能够创新的人才;以及如何避免排挤他们。


假定大教堂风格可以促成创新,而门槛低、流程通畅的市集模式则无能为力,显然是很荒谬的。如果创造源自一个人加一个好主意,那么能吸引成百上千人共同协作的社会环境必然优于一个必须通过政治手腕向上级推销创意的环境(为了避免不被炒鱿鱼,你必须在得到批准之后才能继续研发)。


确实,如果我们检视一下大教堂模式下的软件创新史,不难发现源自其自身的创造凤毛麟角。大企业需要通过大学中的研究获取新知(因此,万圣节文件的作者对Linux对研究成果的快速吸收深表不安)。或者收购一些由于某个创意而组建的小公司。这两种创新均非源自大教堂文化。恰恰相反,很多类似被买断的创见被(万圣节文件作者鼓吹的)“庞大的管理成本”扼杀了。


上面都是一些反证,这里应该把一个正面的例子奉献给读者。我建议大家试试下面的方法:


确立一个你能一以贯之的创新判别标准。比如“发现并加以区分(I know it when I see it)”就满足这个判别条件。
选择一款能和Linux竞争的闭源操作系统,和一个让你可以了解其开发进展的最佳资讯渠道。
在一个月内每天关注Freshmeat和你选择的消息渠道。分别记录下二者中你认为是创新的点子数。
三十天后,汇总两组数据。
在我写下这些文字的日子里,Freshmeat出现了22条新消息。其中有三条看似可以在某方面推动技术革新。虽然这几天Freshmeat不很景气,但是假如有读者在一个月内能通过任何闭源渠道发现这样的三条创新,就真的值得大书特书了。


第十一章 开源的社会语境


这句话一语中的:好的软件都是源自解决开发者的切身之痛,推而广之则是因为很多人也面临着相同的困扰。这将我们带回了“格言1”,或许换个角度重申能让其更具效用:


18.要解决有趣的问题?那就先找到你感兴趣的吧!


To solve an interesting problem, start by finding aproblem that is interesting to you.


卡尔·哈里斯先前的popclinet如此,我的fetchmail也是如此。这个观点已经久为人知。而更有趣(Linux和fetchmail历史中更值得我们关注的)的话题则是出现在下一阶段——由用户和协作开发者组成的庞大的活跃社区,推动了软件的演进。


《人月神话》中,布鲁克斯指出程序员的编程时间不能简单叠加。为已经延期的项目增派人手会让它拖地更久。像我们之前提到的,他指出:项目的复杂度和沟通成本会以开发者人数为基础呈平方指数增长,而业绩仅能直线上升。布鲁克斯定律早已被广泛认可。但是在本书中,有不少开源软件的开发流程可以将这个假说证伪——从经验上看,如果布鲁克斯定律主宰了一切,Linux就不可能出现了。


杰拉尔德·温伯格在其经典著作《程序开发心理学》中对布鲁克斯定律作出了颇具后见之名的重要修正。在其关于“无私编程”的讨论中,温伯格发现一些程序员不会“自扫门前雪”,而是鼓励他人帮助纠错和改进代码。在这样的工作室里,工作进展要显著的多。(最近,肯特·贝克的“极限编程”技巧,将编码者配对组合,令其相互督促。或许可以看作是对加强这种影响的一种尝试)


可能是温伯格的用词让这个结论没有得到应有的认可——把网络黑客说成“毫无私心”未免让人莞尔。但是我认为,他的结论今天看起来比任何时候都更让人信服。


借助“无私编程”的澎湃动力,市集模式有力削弱了布鲁克斯定律的影响。布鲁克斯定律背后的真理并没有被推翻,不过庞大的开发群体和廉价的通讯带来了非线性增长。正是这种增长湮没了它的影响。这就如同牛顿学说和爱因斯坦学说的关系。旧的体系在低能量领域依旧有效。不过一旦你将质量和速度推至足够的高度,就会惊现核爆或者Linux。


Unix的历史应该使得我们对研究Linux(以及我小规模效法李纳斯的实证【注1】)得出的结论有所准备。也就是说,虽然编程依旧需要单打独斗,但是真正伟大的革新却要借助整个社区的关注和智慧。一个闭门造车的开发者将会输给一个懂得如何营造开放,演进环境的开发者。因为在这样的环境下,他可以从几百(甚至几千)人中汲取反馈从而探索设计空间、得到代码捐赠、错误检测、以及其他改进。


但是有几个因素制约了传统的Unix世界没能把这一效果推向极至。其中之一就是来自不同版本许可证、行业秘密、和商业利益的法律限制。另一个(回头看来)是因为当时的因特网还不够强大。


在廉价网络到来之前,有过一些地域性的协作社团,在那里他们提倡温伯格的“无私”编程。开发者可以很容易的吸引到一批高水平的建言者和协作开发人员。贝尔实验室,麻省理工大学的人工智能和计算机实验室,加州大学伯克利分校——这些都是创新的来源,颇具传奇色彩并且继续着影响力。


Linux是第一个致力于并且成功地将全世界当作其智库的项目。在我看来,Linux和万维网同期产生,以及Linux在1993到1994年(ISP产业起飞和主流网络商机爆发的岁月)脱离婴儿期都不是巧合。李纳斯是在网络普及成为可能之后,读懂游戏规则的第一人。


尽管,廉价的网络是Linux模式发展的必要条件,但是我认为这并不足以成为充分条件。另一个关键环节是开发中的领导风格和协作机制——因为用户可以加入协同开发,才使得网络这个媒介的力量能够尽情展示。


那么这种领导风格是怎样的?协作关系又是如何的呢?它们不可能是基于权力关系的——即使能做到,强权的领导关系也不会带来我们所见的成果。在这个问题上,温伯格很恰当的引述了19世纪俄国无政府主义者,皮奥奇·阿列克谢耶维奇·克鲁泡特金在《我的自传》[1]中的论点:


我成长于一个农奴主的家庭,直到进入社会,同当时所有的年青人一样,我信奉诸如命令、秩序、叱责、惩罚的必要性。但是当我早期必须经手一些重要事务并与(自由)人打交道的时候,发现任何错误的指令都会引发严重的后果。于是我开始理解“命令和纪律”与“达成共识”两种行事原则的不同之处。前者在阅兵中起到的作用令人钦佩,但在实际生活中则一文不值。因为现实生活中的目标只能由众人同心协力完成。


“同心协力”正是像Linux这样的项目所需要的——“命令和纪律”对于无政府主义天堂(我们称之为网络)里的志愿者来说则形同虚设。为了有效的运营和竞争,一个想要领导协作项目的黑客必须学会如何有效的激发社区对(克鲁泡特金暗示的)“达成共识”模式的兴趣。还必须学会如何应用李纳斯定律。【注2】


先前我用“德尔菲效应”解释李纳斯定律,但是它本身更像一个生物学和经济学中的自适应系统。Linux世界在很多方面更像是一个自由市场或者生态圈,其中自私的个体都试图将自己的利益最大化,但是在这个过程中却自发形成了一种自我纠正机制,其周密度和有效性令任何中央计划都无法与之媲美。这就是可以“达成共识”的地方。


Linux黑客试图最大化的“效用”并不是传统经济学价值,而是在黑客圈中无形的声望和自我实现(或许有人会将他们的动机描绘成“利他的”,但却忽略了一个事实——利他主义本身就是对利他主义者的一种自我满足)。这样的志愿文化并不罕见;我热衷科幻小说已经很久了。与黑客圈不同,科幻迷们早就清楚地认识到“自我赏识”(自我激励或是赢取同好的赞誉)是志愿者活动背后的基本动力。


李纳斯,成功地在一个大部分由他人完成的项目中扮演了“看门人”的角色,培养利基直到它可以自我维持。可以说他准确的把握了克鲁泡特金“达成共识”的精神。Linux世界里这种类经济学的视角让我们得以看到“共识”是如何应用的。


我们可以把李纳斯的方法,视为一条通过“自我赏识”开创有效市场的路径——用尽可能稳固的方法连接自利的黑客,进而实现必须持续协作才能达成的目标。通过fetchmail项目(虽然规模小点),我证实可以通过效法李纳斯取得成效。或许我做得比他更有意识,更系统。


许多人(特别是不信任自由市场的人)预期(自我主义者的)“自我管理”文化会分崩离析、占山为王、挥霍无度、鬼鬼祟祟、和身怀敌意。但是只需看看丰富、优质、深刻的Linux说明文档就足以将这种预期推翻。程序员讨厌写说明文档似乎是金科玉律,那么这些文档是哪来的?难道Linux黑客都转性了?显然,与自我彰显的Linux自由市场相比,受人支配的商业软件工作室即使有大笔商业资金支持,也生产不出那么优质的文档。


Fetchmail和Linux项目都表明,通过对其他黑客的适当回报,一个优秀的开发者/协调者可以通过因特网网罗众多优秀的协作开发者,进而避免项目在混乱中倾覆。所以,针对布鲁克斯定律我提出反议:


19.倘若开发的协调者拥有不逊于因特网的媒介,又懂得如何避免强权领导,那么群体智慧定要强于单打独斗。


Providedthe development coordinator has a communications medium at least as good as theInternet, and knows how to lead without coercion, many heads are inevitablybetter than one.


我认为开源软件的未来将日益倚重于那些懂得利用李纳斯游戏规则的人,那些告别大教堂投身市集的人。这并不是说个体的远见和才智光辉不再。相反,我认为开源软件的锋芒会属于一种人——他们以独到的远见和才智开始一个项目,之后通过有效的建立志愿者社区来将其扩大。


或许这并不只是开源软件的未来。若论解决难题,没有一个闭源的开发者能与开源社区的智库相提并论。极少有人能雇用超过200人(1999年600人,2000年800人)为fetchmail效力。


或许开源文化会取得最终的胜利,但这并不是因为协作是善,而软件“囤积”是恶(或许你相信后者,不过李纳斯和我却不以为然),而只因开源社区可以为解决一个问题投入数量级的时间,所以闭源世界肯定会在这场进化角逐中落下马来。


注:


1.如今我们有了另一款软件,与fetchmail相比,它对市集模式假设做了更多的测试。这就是EGCS——实验性GNU编译系统(Experimental GNUCompiler System)。


这个项目始于1997年8月中旬,它被视为对早期(《大教堂与市集》公开版本中)观点的有意尝试。GCC项目(GUN C语言编译器,GNU C Compiler)创始人的离开,导致其停滞了许久。大约二十个月之后GCC和EGCS开始了平行的开发——利用相同的因特网开发人员;都以相同的GCC源代码为基础;使用几乎相同的Unix开发工具和开发环境。惟一不同之处在于,对于EGCS我们使用了先前述及的市集策略。而GCC则采用了类似大教堂的开发模式——封闭的开发团队,极少的对外释放。


这是我们能做到的最贴切的核对实验了,其结果颇具戏剧性。几个月里,EGCS就凭借一些特色遥遥领先——更棒的优化设计以及对FORTRAN和C++语言更好的支持。许多人发现与最近的GCC稳定版本相比EGCS发展的更迅速也更可靠。而且主要的Linux发行版都开始改用EGCS了。


1999年4月,自由软件基金会(GCC的官方发起机构)决定解散原始的GCC开发团队,并正式由EGCS接管。


2.当然,克鲁泡特金的批判和李纳斯定律把社会组织控制论抬升到了更广阔的角度。进而联想到软件工程领域的另一则民间法则,康威定律(Conway's Law):“让四个人开发编译器,你就会得到四个(4-pass)编译器”。原始表述更具有一般性:“产品必然是其组织通讯结构的缩影”。简言之就是“方法决定结果”或是“过程变为产品”。


在很多层面上,开源社区没有必要形成与这适应的组织功能结构。网络无处不在:非独因特网,人们的工作也可以形成一种分布式的松散连接,一种对等网络。正是这种联系提供了恰如其分的冗余和缓解。对于这两种网络而言,一个节点的重要性取决于有多少人愿意与其相连。


其中对等部分对社区惊人的生产力至关重要。SNAFU法则[2]发展了克鲁泡特金对权力观点的阐释:“只有平等才能带来真诚的交流,因为下级更习惯于取悦上级而非告知以诚。”创造性的团队协作需要坦诚的交流,所以权属关系的存在必然形成制约。有效摆脱权力羁绊的开源社区向我们展示了这有多可怕:错误、低产能与错失机会!


进而SNAFU法则预言在独裁组织中,随着谄媚越来越多,决策者和事实的剥离也愈发严重。其在传统软件开发中所扮演的角色显而易见:下级有很多动机去隐匿、漠视、淡化问题。一旦这个过程转化成了产品,就是一场灾难。


译者按:


1.皮奥奇·阿列克谢耶维奇·克鲁泡特金:Пётр Алексе́евичКропо́ткин (1842-1921) 俄国无政府主义者、地理学家、政治哲学家,他认为改善人类现状的方法是合作而不是竞争。他对俄国和英国的无政府主义运动产生了很大的影响。《我的自传》是巴金的译作,也是巴金认为对自己影响最大的一本书。其英文版名为《Memoirs of a Revolutionist》。


2. SNAFU:“snafu”是二战时期军队中使用的一条缩略语。也就是Situationnormal all fucked up(好日子都他妈搞砸了)。后来也写为Situation normal all fouled up(平静的状态被搅乱了)。黑客则借此解释集权模式的恶果。


第十二章 关于管理和马其诺防线


1997年最初的《大教堂与市集》以这样的预见收束——程序员/无政府主义者快乐的网络部族,战胜并压倒了等级森严的传统闭源世界。


然而,许多人对此持怀疑态度,他们提出的问题应该得到中正的回应。多数对市集模式的异议可以归结为以下观点:开源支持者们低估了传统管理对生产力的提升作用。


传统思维的软件开发经理经常会指责开源项目组的创建-变动-解散太随意了。这种随意性大大抵消了(对于单个闭源开发者来说)开源社区在人数上的优势。他们会指出软件开发取决于长时间的持续投入,和预期的消费者持续购买程度。而不只是取决于有多少人往锅里扔骨头,然后等着它炖熟。


无可否认,这些论调有一定道理。其实我早就在《魔法大锅炉》(The Magic Cauldron)一文中预计增值服务将会是未来软件业的经济命脉。


但是这个论调却回避了一个重要的问题,它暗自假设开源开发不能提供持续的投入。事实上,有些开源项目已经在相当长的周期里保持了一致的发展方向和有效的维护社区,而不需要传统管理中必不可少的激励模式和制度约束。GNU的Emacs编辑器就是一个极端的、发人深思的例子。不管人事变动有多么频繁(实际上一以贯之的只有作者一人),几百位贡献者还是在长达15年的时间里用全心全意的投入建筑了一个统一的架构。没有一个闭源编辑器能问津这个长寿记录。


这到是提供了一个质疑传统软件开发模式(和大教堂与市集模式的争论不相干)的原因。如果GNU的Emacs在15年的岁月里保持了一致的架构;如果一个像Linux这样的操作系统在硬件和平台技术飞速变换的8年里也做到了这一点;如果(事实如此)许多设计精良的开源项目维系了超过5年的时间——那么我们有资格发问,传统开发的巨额管理费用(如果有的话)究竟给我买到了什么?


不管是什么,它显然不包括按期、按预算、按指定功能完成计划的可靠运营手段。如果能满足其中一条,就是一个罕见的“管理好”的项目了,更不用说全部了。它看来也不包括在让项目在开发过程种拥有适应技术和经济环境变化的能力。在这些方面开源社区已经遥遥领先了(比方说,你可以对比一下因特网30年的历史和那些专利网络短命的半衰期,也可以对比一下从16位到32位Linux毫不费力的升级和微软为此消耗的成本。特别要提醒你的是,Linux可不是只围绕英特尔系列打转,而是支持了包括64位Alpha芯片在内的十几家芯片厂商的产品)。


很多人认为从传统模式产品中可以买到法律保障——一旦出现问题会有人站出来负责,并得到补偿。但是这只是个幻觉,大部分软件许可证甚至没有写入商业担保,更不用说履行了。因为软件不工作而获得赔付的成功案例基本为零。退一步讲,就算有很多成功案例,你也不能因为有了打官司的对象就安心了啊!软件是为我们工作的,不是拿来打官司用的!


那么这些管理成本到底买来了什么呢?


要理解这个问题,就要看看软件开发经理是怎么想的。我认识的一位看似工作很出色的女经理说,软件项目管理有以下五项功能:


确立目标,并确保大家朝着同一个方向努力
监督,保证关键细节无一遗漏
激励,让大家去做一些枯燥但是必须的苦力活
组织,分配人手以达到最佳产出
资源监护,满足项目所需 


显然所有这些目标都是有价值的。但是在开源模式以及其社会语境中,这些目标会变得出奇的不靠谱。我们颠倒次序来讨论。


我的朋友告诉我,许多“资源监护”基本都是防御性的。一旦你有了人手、机器、办公空间,就不得不防备其他经理与你竞争相同的资源,也要防备上级攫取有限资源中的精华。


但是开源开发者都是志愿的,他们通过能力和兴趣自主选择项目(即使他们因为开源开发而获得报酬,这条也依旧适用)。志愿的特点会自动解决资源监护中的“进攻方”,因为大家桌上放的全部是自己的资源。这对管理者而言,意味着几乎没有必要进行传统的“防御”。


总之,在一个拥有廉价电脑和快速因特网链接的世界里,我们不约而同的发现惟一真正的稀缺资源是技术关注。本质上,开源项目永远不会为了争夺机器、网络、办公空间而建立。只有当开发者失去兴趣的时候它们才会消亡。


除此之外,加倍重要的是开源黑客们通过基于自主选择的“自我组织”来达到最大产能——社会环境对于能力的选择是近乎残酷的。我的那位朋友对开源世界和大型闭源项目都很熟悉,她认为开源的成功应归功于其只吸纳了程序员中最具才华的5%。而她则将自己的时间都消耗在如何组织剩下的95%上了。因此她在一线上感受到了这种众所周知的差异——对于刚刚够格的程序员,精兵强将足以以一顶百。


这个巨大差异总是引发一个尴尬的问题:无论对于单个项目还是整个行业,甩掉能力最差的50%会不会好些?明智的经理早就明白,如果传统管理的惟一作用是为了将最差部分由净亏损转变为边际收益的话,未免太得不偿失了。


开源社区的成功把这个问题变得相当尖刻,因为我们提供了硬性的证据:与管理整栋楼“身在曹营心在汉”的人相比,通过因特网招募自主选择的志愿者算是相当的“物美价廉”了。


这恰好把我们转向了“动机”的问题,对于我朋友的观点,有另外一种等价的,也时常听到的描述:传统开发管理是对缺少动力的程序员的必要补偿,否则他们不会好好干活。


这个回答通常伴随着一个说法,那就只能指望开源社区做那种“迷人”的或者技术上有趣的工作,否则都会半途而废(或敷衍了事)——除非能把他们变成那种经理鞭打下收入微薄的苦工。我在《开拓智域》(Homesteading the Noosphere)一文中就心理学和社会学的角度阐述了对这一观点的质疑。就目前而言,我们暂且假定这个推论正确会更有趣!


如果传统的、闭源的、管理臃肿的软件开发模式只能托庇于一种令问题愈发枯燥的马其诺防线的话,那他们就要祈祷了,祈祷在每个领域都没人能发现问题的真正趣味,祈祷没人发现绕过防线的路径。因为对于“枯燥”的领域,一旦有开源软件加入战团,用户就会立刻明白——终于有人发现了问题的迷人之处并着手解决了!对软件业,如同其他的创造性工作一样,这比单一的金钱激励要有效的多。


只是为了获取激励而采用传统的管理结构,也许是个好战术,但绝非优秀的战略——短期的胜利换来长效的溃败。


说到这,传统开发管理和开源开发相比,在两点上(组织和资源监护)显然是不智之举,对于第三点(激励)则显得鼠目寸光。被团团包围的可怜的传统经理人也不会等到“监督”的任何援兵了。因为对于确保细节无一遗漏,开源社区强健的同行评议要胜过所有传统方法。


我们能把“确立目标”留下来作为接受传统管理开销的理由吗?或许吧。如果这样做了,我们就必须有充分的理由相信这些管理委员会和社团有能力制定出更具远见卓识的目标,而且要做的比开源世界中同司此职的项目领导和“部族长老”们更加成功。


这从表面上就很难说得通。并非开源一方的发难(Emacs的长寿?李纳斯以“统治世界”的说辞集结“游牧部落”的能力?)打破了平衡。相反,是传统模式对目标的制定令自己处境尴尬。


这里有一个久负盛名的民间定理是关于软件工程的——60%到75%的传统软件项目要么半途而废了,要么就是被目标用户拒之门外了。如果这个数字和事实贴切的话(我至今还未曾遇到过有经验的管理者否认这点),那么就可以说大多数的项目都选错了目标,要么(a)不切实际,要么(b)错得离谱。


这也正是如今软件工程领域大家一听到“管理委员会”就凉彻脊骨的原因,甚至(或者尤其)是当听众本身就是管理者的时候。原本只有程序员才会抱怨的日子早就过去了,现如今呆伯特[1]已经跳上了主管们的案头。


给传统软件开发经理的答复很简单,如果真的只是开源社区低估了传统管理的价值,那么你们其中的许多人又何苦对自己的工作进程不屑一顾呢?


开源社区的例子又一次把问题变得尖刻了——因为我们乐在其中。我们的创新游戏已经在技术上、市场份额上、以及观念上取得了惊人的成功晋级。我们正在证实,我们不仅可以创造更好的软件,并且(证实了)快乐是一种财富!


本文第一版的两年半之后,我能用来收束本书的最激进的观点就已经不再是“开源领军软件世界”了。毕竟,如今许多西服革履的人[2]也认同了这种可能性。


进而,我打算提出一则关于软件的更宽泛的经验(或许这事关每一种创新或专业工作)。人们通常在恰到好处的挑战中享受工作的乐趣。不要简单到兴味索然,也不要难到不切实际。一个既没有被浪费,也没有因为病态目标和进程冲突而不堪重负的程序员才是快乐的。乐趣决定效率。


一旦你对自己的工作进程感到恐惧和厌恶(哪怕你改用悬挂呆伯特卡通这种改头换面的讽刺方式)通常就应该视作过程失败的信号。快乐、幽默、和趣味才是真正的财富。我不是为了押韵才选了“快乐部族”这个词,Linux用一只稚气未脱、让人想抱抱的企鹅当吉祥物也不是为了开玩笑的。


或许,开源最重要的影响是教会了我们——乐趣才是创造性工作中最有用经济效能。 


译者按: 


1.呆伯特(Dilbert),是美国漫画家兼作家史考特·亚当斯(Scott Adams)的著名职场卡通人物。热爱科技,憨厚老实的呆伯特在工作上经常被主管过份要求、亏待或利用。如今dilbert(首字母小写)已经成为了一个动词。比如说 “I’m dilberted”就是说“我被老板欺负了”“工作太苛刻了”等等。可以从这里看到每日的新作:http://www.dilbert.com/ 


2.西服革履:原文中作“people in suits”。黑客的生活是很自由的,不需要着正装。就算是公司的普通职员也只需着正装而不必穿套装(Suits)。所以这个说法通常被黑客用于指代和揶揄公司高管。 


3.本章中提及了作者的其他两部作品:《魔法大锅炉》和《开拓智域》。我采用的都是网上已有中文译版的译名。


后记:网景投身市集


与历史同行,是一种奇妙的感觉……


1998年1月22日,大约在我的《大教堂与市集》初版七个月后,网景通讯公司宣布了开放网景浏览器源代码的计划,事前我一无所知。


不久之后,网景的副执行总裁兼首席技术官埃里克·哈恩(Eric Hahn)给我发来了一封电邮:“首先,我要代表网景的全体同仁,感谢你指引我们走到了这一步。你的思想和著述给了这个决定至关重要的启迪。”


接下来的一周,我应网景之邀飞抵矽谷。和他们高管以及技术人员共同参与了一个为期一天(1998年2月4日)的战略会议。会上,我们决定了网景的源代码释放计划和许可证相关事宜。


几天后我写到:


网景正打算在商业世界里给我们提供一场大规模的、真正全球化的市集尝试。开源文化正在面临考验:如果网景此举失败,开源文化就会信誉扫地,商业世界在未来十年里都会对其不屑一顾。


另一方面,这也是个绝佳的机会。华尔街和其他地方对此举最初报以谨慎的肯定。我们也赢取了一个证明自己的机会。如果网景能借此重夺市场份额,或许会引发软件业一场等待许久的革命。


接下来的一年将会颇具教育意义,也会很有趣。


确实如此,2000年中期我修订此文之际,后来名为Mozilla的开发项目只能算是刚刚合格的成功。它完成了网景的最初目标——防止微软垄断把持浏览器市场。当然也有显著的胜利(特别是下一代Gecko排版引擎的发布)。


然而,却没能得到来自网景之外,Mozilla创立者最初期望的那种开发规模。问题是,似乎在相当长的一段时间里,Mozilla的发布实际上都破坏了市集模式的一条基本原则。它没有一个能让潜在贡献者可以轻松上手和眼观其效的东西。(直到发布一年多之后,对Mozilla进行代码级的编写,还必须要通过私有Motif库的许可证)


最消极的是(以外界的观点来看),在计划开始之后长达两年半的时间里,Mozilla团队都没能开发出一个工业级质量的浏览器——而且在1999年,一个项目骨干的拂袖而去引发了不小的影响。他抱怨管理不力,错失良机。“开源,”他恰当的评价道,“不能点石成金!”


确实不能,如今(2000年11月)Mozilla项目经过长期的恢复,比杰米·泽文斯基(Jamie Zawinski)递交辞呈的时候有了戏剧性的提高——最近几周的每夜释放版(nightly releases)终于在通向产品可用性上迈出了关键一步。但是杰米是对的,对于目标错乱、代码一团乱麻、或者患有其他工程慢性病的现有项目,开源并不能确保力挽狂澜。Mozilla成了同时展示开源如何成功和如何失败的案例。


然而,与此同时,开源的理念已经在其他地方开花结果。自从网景计划公布以来,我们目睹了一场对开源投诸兴趣的井喷。对Linux操作系统而言,持续的成功既是动力也是驱策。Mozilla触发的潮流正在加速前行。


《大教堂与市集》 参考书目


我多次引用了弗雷德里克·P·布鲁克斯的经典著作《人月神话》(The Mythical Man-Month),在许多层面,他的观察至今还是颇具洞见的。我衷心的推荐其1986年刊发的包含《没有银弹》(No SilverBullet)25周年纪念版。


Assison-Wesley社,ISBN 0-201-83595-9 (中文版:清华大学出版社,2002 ISBN 978-7-302-05932-5)


这个新版本还包含一份非常珍贵的回顾,一份布鲁克斯在20年后对文中少数几个没能经得住时间考验的论点的回顾。在本文第一版几近完工的时候,我首次读到了这篇回顾,并惊讶的发现布鲁克斯把市集模式归功于微软!(事实证明这显然是不正确的,1998年我们通过“万圣节文件”获知,微软内部开发团体朋党林立,不可能存在市集模式所必须的全面代码共享)


杰拉尔德·温伯格在《程序开发心理学》(The Psychology Of Computer Programming)引入了“无私编程”的概念,尽管这个名字不是很舒服。虽然他远非意识到“命令和纪律”空无一用的第一人,但是他可能是第一个把这个观点和软件开发联系起来的人。


纽约,Van Nostrand Reinhold社,1971(中文版:清华大学出版社,2003,ISBN 7-302-07026-1;中文版书名《程序开发心理学(银年纪念版)》,即“Silver Anniversary Edition”,也就是二十五周年纪念版)


对前Linux时代的Unix文化颇有研究的理查德·P·加百利(RichardP. Gabrie),在其1989年的文章《LISP:好消息,坏消息,以及如何做大》(LISP: Good News, Bad News, and How To Win Big)中,很不情愿的描述了一种原始准市集模式的优越性。尽管在某些方面有点过时,此文还是受到不少LISP迷(包括我)的推崇。一位读者提醒我,其中《无用之用》(Worse Is Better)的章节看上去像是对Linux的预言。


该文网址:http://www.naggum.no/worse-is-better.html


达·马可(De Marco)和利斯特(Lister)的《人件:高产的项目和团队》是一部被忽视了的佳作。我很高兴布鲁克斯在其回顾中引用了此书。虽然文中所述极少可以被直接用于Linux和开源社区,但是作者对创造性工作先决条件的论断,却值得每个希望将市集模式精华移入商业领域的人思考。


纽约, Dorset House社,1987, ISBN 0-932633-05-6(中文版:清华大学出版社,2003,ISBN7-302-06384-2;中文版译名《人件》,且是第二版)


最后,我必须承认我差点就把本书定名为《The Cathedral and the Agora》。“Agora”是指古希腊的公开市场或者公众机会场所。马克·米勒(Mark Miller)和埃里克·德雷克斯勒(Eric Drexler)在关于“agoric systems”系列的开创性文章中描绘了一种像市场一样自然生成的计算机生态学。正是此文,让我在五年后(当Linux不期而至的时候)深刻的领悟了开源文化中类似现象。


《大教堂与市集》 致谢


本文的改进得益于众多朋友与我交流并提出意见。特别要感谢Jeff Dutky <dutky@wam.umd.edu>, 他提出了“调试可平行展开”的观点,并帮我完成了其后的分析。同样要感谢Nancy Lebovitz <nancyl@universe.digex.net>,她建议我效法温伯格引述克鲁泡特金。来自General Technics邮件列表的Joan Eslinger <wombat@kilimanjaro.engr.sgi.com>和Marty Franz <marty@net-link.net>提供了关于可读性的批评。Glen Vandenburg <glv@vanderburg.org>指出了贡献人群自我选择的重要性,并对改进“冗余设计”做出了富有成效的探索。Daniel Upper <upper@peak.org>指出了自然界中的类似现象。非常感谢费城Linux用户组(PLUG),他们是本书第一个公开版的第一批测试读者。Paula Matuszek <matusp00@mh.us.sbphrd.com> 为我提供了软件管理方面的实践知识。Phil Hudson <phil.hudson@iname.com> 让我明白,黑客的社会组织结构反映了其软件结构,反之亦然。John Buck <johnbuck@sea.ece.umassd.edu>指出MATLAB可以作为Emacs的有益类比。Russell Johnston <russjj@mail.com> 让我意识到《要多少只眼来驯服复杂》章节中关于一些机制的讨论。最后,感谢李纳斯提供了许多有用的建议,以及其一早就对本作表现出的认可。
展开阅读全文

没有更多推荐了,返回首页