相關閱讀 |
>>> 讀書—連接古今充實信仰 >>> | 簡體 傳統 |
二 邮件必达
自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”用来指代一个计划或者原型,我认为不能直接译为“一个”所以用了代词“它”放宽其概念。
埃里克.斯蒂芬.雷蒙 2014-07-01 18:20:26
稱謂:
内容: