天天看點

大教堂與市集——Eric Raymond

大教堂與市集

說明:

本文的作者Eric Raymond是Open Source Software領域的領袖,這方面許多

新的思想正是從他那兒産生的,同時他也是UNIX上最流行的Email軟體Fetchmail

的作者。

下面這篇文章有點兒長,然而它是值得你去耐心把它讀完的。文章以Fetchmail

為例,讨論了Internet上集市風格的開發方式。

我們應該感謝HansB,是他把這篇長文章翻譯成了中文。

Eric的首頁位址在:http://www.tuxedo.org/~esr/

-------------------------------------------------------------------------

一. 大教堂和市集

  Linux的影響是非常巨大的。甚至在5年以前,有誰能夠想象一個世界級的操

作系統能夠僅僅用細細的Internet連接配接起來的散布在全球的幾千個開發人員有以業

餘時間來創造呢?

我當然不會這麼想。在1993年早期我開始注意Linux時,我已經參與Unix

和自由軟體開發達十年之久了。我是八十年代中期GNU最早的幾個參與者之一。我

已經在網上釋出了大量的自由軟體,開發和協助開發了幾個至今仍在廣泛使用的

程式(Nethack,Emacs VC和GND模式,xlife等等)。我想我知道該怎樣做。

  Linux推翻了許多我認為自己明白的事情。我已經宣揚小工具、快速原型和演

進式開發的Unix福音多年了。但是我也相信某些重要的複雜的事情需要更集中化的,

嚴密的方法。我相信多數重要的軟體(作業系統和象Emacs一樣的真正大型的工具)

需要向建造大教堂一樣來開發,需要一群于世隔絕的奇才的細心工作,在成功之前

沒有beta版的釋出。

Linus Torvalds的開發風格(盡早盡多的釋出,委托所有可以委托的事,對所

有的改動和融合開放)令人驚奇的降臨了。這裡沒有安靜的、虔誠的大教堂的建造

工作——相反,Linux團體看起來像一個巨大的有各種不同議程和方法的亂哄哄的

集市(Linux歸檔站點接受任何人的建議和作品,并聰明的加以管理),一個一緻

而穩定的系統就象奇迹一般從這個集市中産生了。

  這種設計風格确實能工作,并且工作得很好,這個事實确實是一個沖擊。在我

的研究過程中,我不僅在單個工程中努力工作,而且試圖了解為什麼Linux世界不

僅沒有在一片混亂中分崩離析,反而以大教堂建造者們不可想象的速度變得越來越

強大。

  到了1996年中,我想我開始了解了。我有一個極好的測試我的理論的機會,

以一個自由軟體計劃的形式,我有意識的是用了市集風格。我這樣做了,并取得了

很大的成功。

在本文的餘下部分,我将講述這個計劃的故事,我用它來明确一些自由軟體高

效開發的格言。并不是所有這些都是從Linux世界中學到的,但我們将看到Linux世

界給予了它們一個什麼樣的位置。如果我是正确的,它們将使你了解是什麼使Linux

團體成為好軟體的源泉,幫助你變得更加高效。

二. 郵件必須得通過

  1993年以前我在一個小的免費通路的名為Chester County InterLink的ISP

的做技術工作,它位于Pennsylvania的West Chester。(我協助建立了CCIL,并寫了

我們獨特的多使用者BBS系統——你可以telnet到locke.ccil.org來檢測一下。今天它

在十九條線上支援三千的使用者)。這個工作使我可以一天二十四小時通過CCIL的56K

專線連在網上,實際上,它要求我這麼做!

  是以,我對Internet email很熟悉。因為複雜的原因,很難在我家裡的機器

(snark.thyrsus.com)和CCIL之間用SLIP工作。最後我終于成功了,但我發現不

得不時常telnet到locke來檢查我的郵件,這真是太煩了。我所需要的是我的郵件

發送到snark,這樣biff(1)會在它到達時通知我。

  簡單地sendmail的轉送功能是不夠的,因為snark并不是總在網上而且沒有一

個靜态位址。我需要一個程式通過我的SLIP連接配接把我的本地發送的郵件拉過來。

我知道這種東西是存在的,它們大多使用一個簡單的協定POP(Post Office

Protocol)。而且,locke的BSD/OS作業系統已經自帶了一個POP3伺服器。

  我需要一個POP3客戶。是以我到網上去找到了一個。實際上,我發現了三、

四個。我用了一會pop-perl,但它卻少一個明顯的特征:抽取收到的郵件的位址

以便正确回複。

  問題是這樣的:假設locke上一個叫“joe”的人向我發了一封郵件。如果我

把它取到snark上準備回複時,我的郵件程式會很高興地把它發送給一個不存在的

snark上的“joe”。手工的在位址上加上“@ccil.org”變成了一個嚴酷的痛苦。

  這顯然應是計算機替我做的事。(實際上,依據RFC1123的5.2.18節,

sendmail應該做這件事)。但是沒有一個現存的POP客戶知道怎樣做!于是這就給

我們上了第一課:

  1.每個好的軟體工作都開始于搔到了開發者本人的癢處。

也許這應該是顯而易見的(“需要是發明之母”長久以來就被證明是正确的),

但是軟體開發人員常常把他們的精力放在它們既不需要也不喜歡的程式,但在

Linux世界中卻不是這樣——這解釋了為什麼從Linux團體中産生的軟體品質都如

此之高。

  那麼,我是否立即投入瘋狂的工作中,要編出一個新的POP3客戶與現存的那

些競争呢?才不是哪!我仔細考察了手頭上的POP工具,問自己“那一個最接近我

的需要?”因為:

  2.好程式員知道該寫什麼,偉大的程式員知道該重寫(和重用)什麼。

  我并沒有聲稱自己是一個偉大的程式員,可是我試着效仿他們。偉大程式員

的一個重要特點是建設性的懶惰。他們知道你是因為成績而不是努力得到獎賞,

而且從一個好的實際的解決方案開始總是要比從頭幹起容易。

  例如,Linux并不是從頭開始寫Linux的。相反的它從重用Minix(一個386機

型上的類似Unix的微型作業系統)的代碼和思想入手。最後所有的Minix代碼都消

失或被徹底的重寫了,但是當它們在的時候它為最終成為Linux的雛形做了鋪墊。

  秉承同樣的精神,我去尋找良好編碼的現成的POP工具,用來作為基礎。

  Unix世界中的代碼共享傳統一直對代碼重用很友好(這正是為什麼GNU計劃不

管Unix本身有多麼保守而選取它作為基礎作業系統的原因)。Linux世界把這個傳

統推向技術極限:它有幾個T位元組的源代碼可以用。是以在Linux世界中花時間尋

找其他幾乎足夠好的東西,會比在别處帶來更好的結果。

  這也适合我。加上我先前發現的,第二次尋找找到了9個候選者——fetchPOP

,PopTart,get-mail,gwpop,pimp,pop-perl,popc,popmail 和 upop)。我

首先標明的是“fetchpop”。我加入了頭标重寫功能,并且做了一些被作者加入

他的1.9版中的改進。

  但是幾個星期之後,我偶然發現了Carl Harris寫的“popclient”的代碼,

然後發現有個問題,雖然fetchpop有一些好的原始思想(比如它的守護程序模式),

它隻能處理pop3,而且編碼的水準相當業餘(Seung-Hong是個很聰明但是經驗不足

的程式員),Carl的代碼更好一些,相當專業和穩固,但他的程式缺少幾個重要的

相當容易實作的fetchpop的特征(包括我自己寫的那些)。

  繼續呢還是換一個? 如果換一個的話,作為得到一個更好開發基礎的代價,

我就要扔掉我已經有的那些代碼。

  換一個的一個實際的動機是支援多協定,pop3是用的最廣的郵局協定,但并

非唯一一個,Fetchpop和其餘幾個沒有實作POP2.RPOP,或者APOP,而且我還有一

個為了興趣加入IMAP(Internet Message Access Protocol,最近設計的最強大的

郵局協定)的模糊想法。

  但是我有一個更加理論化的原因認為換一下會是一個好主意,這是我在Linux

很久以前學到的:

 3.“計劃好抛棄,無論如何,你會的”(Fred Brooks,《神秘的人月》第11章)

  或者換句話說,你常常在第一次實作一個解決方案之後才能了解問題所在,

第二次你也許才足夠清楚怎樣做好它,是以如果你想做好,準備好推翻重來至少

一次。

  好吧(我告訴自己),對fetchpop的嘗試是我第一次的嘗試,是以我換了一下。

  當我在1996年6月25日把我第一套popclient的更新檔程式寄給Carl Harris之

後,我發現一段時間以前他已經對popclient基本上失去了興趣,這些代碼有些陳

舊,有一些次要的錯誤,我有許多修改要做,我們很快達成一緻,我來接手這個

程式。不知不覺的,這個計劃擴大了,再也不是我原先打算的在已有的pop客戶上

加幾個次要的更新檔而已了,我得維護整個的工程,而且我腦袋裡湧動着一些念頭

要引起一個大的變化。

  在一個鼓勵代碼共享的軟體文化裡,這是一個工程進化的自然道路,我要指

出:

 4. 如果你有正确的态度,有趣的問題會找上你的,但是Carl Harris的态度甚

至更加重要,他了解:

 5.當你對一個程式失去興趣時,你最後的責任就是把它傳給一個能幹的後繼者。

  甚至沒有商量,Carl和我知道我們有一個共同目标就是找到最好的解決方

案,對我們來說唯一的問題是我能否證明我有一雙堅強的手,他優雅而快速的寫

出了程式,我希望輪到我時我也能做到。

三. 擁有使用者的重要性

  于是我繼承了popclient,同樣重要的是,我繼承了popclient的使用者基礎,

使用者是你所擁有的極好的東西,不僅僅是因為他們顯示了你正在滿足需要,你做

了正确的事情,如果加以适當的培養,他們可以成為合作開發者。

  Unix傳統另一有力之處是許多使用者都是黑客,因為源優碼是公開的,他們可

以成為高效的黑客,這一點在Linux世界中也被推向了令人高興的極緻,這對縮短

調試時間是極端重要的,在一點鼓勵之下,你的使用者會診斷問題,提出修訂建

議,幫你以遠比你期望快得多的速度的改進代碼。

 6. 把使用者當做協作開發者是快速改進代碼和高效調試的無可争辯的方式。

  這種效果的力量很容易被低估,實際上,幾乎所有我們自由軟體世界中的人

都強烈低估了使用者可以多麼有效地對付系統複雜性,直到Linus讓我們看到了這一

點。

  實際上,我認為Linus最聰明最了不起的工作不是建立了Linux核心本身,而

是發明了Linux開發模式,當我有一次當着他的面表達這種觀點時,他微笑了一

下,重複了一句他經常說的話:“我基本上是一個懶惰的人,依靠他人的工作來

擷取成績。”象狐狸一樣懶惰,或者如Robert Heinlein所說,太懶了而不會失

敗。

  回顧起來,在GNU Emacs Lisp庫和Lisp代碼集中可以看到Linux方法的成功,

與Emacs的C核心和許多其他FSF的工具相比,Lisp代碼庫的演化是流動性的和使用者

驅動的,思想和原型在達到最終的穩定形式之前往往要重寫三或四次,而且經常

利用Internet的松散合作。

  實際上,我自己在fetchmail之前最成功的作品要算Emacs VC模式,它是三個

其他的人通過電子郵件進行的類似Linux的合作,至今我隻見過其中一個人

(Richard Stallman),它是SCCS、RCS和後來的CVS的前端,為Emacs提供“one-

touch”版本控制操作,它是從一個微型的、粗糙的别人寫好的sccs.el模式開始

演化的,VC開發的成功不像Emacs本身,而是因為Emacs Lisp代碼可以很快的通過

釋出/測試/改進的過程。

  (FSF的試圖把代碼放入GPL之下的政策有一個未曾預料到的副作用,它讓FSF

難以采取市集模式,因為他們認為每個想貢獻二十行以上代碼的人都必須得到一

個授權,以使受到GPL的代碼免受版權法的侵擾,具有BSD和MITX協會的授權的用

戶不會有這個問題,因為他們并不試圖保留那些會使人可能受到質詢的權力)。

 四. 早釋出、常釋出

  盡量早盡量頻繁的釋出是Linux開發模式的一個重要部分,多數開發人員(包

括我)過去都相信這對大型工程來說是個不好的政策,因為早期版本都是些充滿錯

誤的版本,而你不想耗光使用者的耐心。

這種信仰強化了建造大教堂開發方式的必要性,如果目标是讓使用者盡可能少

的見到錯誤,那你怎能不會僅僅每六個月釋出一次(或更不經常),而且在釋出之

間象一隻狗一樣辛勤“捉蟲”呢? Emacs C核心就是以這種方式開發的,Lisp庫,

實際上卻相反,因為有一些有FSF控制之外的Lisp庫,在那裡你可以獨立于Emacs

釋出周期地找尋新的和開發代碼版本。

  這其中最重要的是Ohio州的elisp庫,預示了今天的巨大的Linux庫的許多特

征的精神,但是我們很少真正仔細考慮我們在做什麼,或者這個庫的存在指出了

FSF建造教堂式開發模式的什麼問題,1992年我曾經做了一次嚴肅的嘗試,想把

Ohio的大量代碼正式合并到Emacs的官方Lisp庫中,結果我陷入了政治鬥争中,徹

底失敗了。

  但是一年之後,在Linux廣泛應用之後,很清楚,一些不同的更加健康的東西

誕生了,Linus的開發模式正好與建造教堂方式相反,Sunsite和tsx-11的庫開始

成長,推動了許多釋出。所有這些都是聞所未聞的頻繁的核心系統的釋出所推動

的。

  Linus以所有實際可能的方式把它的使用者作為協作開發人員。

 7. 早釋出、常釋出、聽取客戶的建議

  Linus的創新并不是這個(這在Unix世界中是一個長期傳統),而是把它擴充到

和他所開發的東西的複雜程度相比對的地步,在早期一天一次釋出對他來說都不

是罕見的!而且因為他培育了他的協作開發者基礎,比其他任何人更努力地充分利

用了Internet進行合作,是以這确實能行。

  但是它是怎樣進行的呢?它是我能模仿的嗎?還是這依賴于Linus的獨特天才?

  我不這樣想,我承認Linus是一個極好的黑客(我們有多少人能夠做出一個完

整的高品質的作業系統核心?),但是Linux并不是一個令人敬畏的概念上的飛躍,

Linus不是(至少還不曾是)象Richard stallman或James Gosling一樣的創新天

才,在我看來,Linus更象一個工程天才,具有避免錯誤和開發失敗的第六感覺,

掌握了發現從A點到B點代價最小的路徑的決竅,确實,Linux的整個設計受益于這

個特質,并反映出Linus的本質上保守和簡化設計的方法。

  如果快速的釋出和充分利用Internet不是偶然而是Linus的對代價最小的路徑

的洞察力的工程天才的内在部分,那麼他極大增強了什麼?他建立了什麼樣的方法?

  問題回答了它自己,Linus保持他的黑客使用者經常受到激勵和獎賞:被行動的

自我滿足的希望所激勵,而獎賞則是經常(甚至每天)都看到工作在進步。

  Linus直接瞄準了争取最多的投入調試和開發的人時,甚至冒代碼不穩定和一

旦有非常棘手的錯誤而失去使用者基礎的險,Linus似乎相信下面這個:

 8. 如果有一個足夠大的beta測試人員和協作開發人員的基礎,幾乎所有的問題

都可以被快速的找出并被一些人糾正。

  或者更不正式的講:“如果有足夠多的眼睛,所有的錯誤都是淺顯的”(群衆

的眼睛是雪亮的),我把這稱為“Linus定律”。

  我最初的表述是每個問題“對某些人是透明的”,Linus反對說,了解和修訂

問題的那個人不一定非是甚至往往不是首先發現它的人,“某個人發現了問題”,

他說,“另一個了解它,我認為發現它是個更大的挑戰”,但是要點是所有事都趨

向于迅速發生。

  我認為這是建造教堂和集市模式的核心差別,在建造教堂模式的程式設計模式看

來,錯誤和程式設計問題是狡猾的、陰險的、隐藏很深的現象,花費幾個月的仔細檢

查,也不能給你多大確定把它們都挑出來的信心,是以很長的釋出周期,和在長

期等待之後并沒有得到完美的版本釋出所引起的失望都是不可避免的。

  以市集模式觀點來看,在另一方面,我們認為錯誤是淺顯的現象,或者至少

當暴露給上千個熱切的協作開發人員,讓他們來對每個新釋出進行測試的時候,

它們很快變得淺顯了,是以我們經常釋出來獲得更多的更正,作為一個有益的副

作用,如果你偶爾做了一個笨拙的修改,也不會損失太多。也許我們本不應該這

樣的驚奇,社會學家在幾年前已經發現一群相同專業的(或相同無知的)觀察者的

平均觀點比在其中随機挑選一個來得更加可靠,他們稱此為“Delhpi效應”,

Linus所顯示的證明在調試一個作業系統時它也适用——Delphi效應甚至可以戰勝

作業系統核心一級的複雜度。

  我受Jeff Dutky (dutky @ wam.umd.edu)的啟發指出Linus定律可以重新表述

為“調試可以并行”,Jeff觀察到雖然調試工作需要調試人員和對應的開發人員

相交流,但它不需要在調試人員之間進行大量的協調,于是它就沒有陷入開發時

遇到的平方複雜度和管理開銷。

在實際中,由于重複勞動而導緻的理論上的喪失效率的現象在Linux世界中并

不是一個大問題,“早釋出、常釋出政策”的一個效果就是利用快速的傳播回報

修訂來使重複勞動達到最小。

  Brooks甚至做了一個與Jeff相關的更精确的觀察:“維護一個廣泛使用的程

序的成本一般是其開發成本的40%,奇怪的是這個成本受到使用者個數的強烈影響,

更多的使用者發現更多的錯誤”(我的強調)。

更多的使用者發現更多的錯誤是因為更多的使用者提供了更多測試程式的方法,

當使用者是協作開發人員時這個效果被放大了,每個找尋錯誤的人都有自己稍微不

同的感覺和分析工具,從不同角度來看待問題。“Delphi效應”似乎因為這個變

體工作變得更加精确,在調試的情況下,這個變體同時減小了重複勞動。

  是以加入更多的beta測試人員雖不能從開發人員的P.O.V中減小“最深”的錯

誤的複雜度,但是它增加了這樣一種可能性,即某個人的工具和問題正好比對,

而這個錯誤對這個人來說是淺顯的。

  Linus也做了一些改進,如果有一些嚴重的錯誤,Linux核心的版本在編号上

做了些處理,讓使用者可以自己選擇是運作上一個“穩定”的版本,還是冒遇到錯

誤的險而得到新特征,這個戰略還沒被大多數Linux黑客所仿效,但它應該被仿

效,存在兩個選擇的事實讓二者都很吸引 人。

  

五. 什麼時候玫瑰不是玫瑰?

  在研究了Linus的行為和形成了為什麼它成功的理論之後,我決定在我的工程

(顯然沒有那麼複雜和雄心勃勃)裡有意識的測試這個理論。

但我首先做的事是熟悉和簡化Popclient。 Carl Harris的實作非常好,但是

有一種對許多C程式來說沒有必要的複雜性。他把代碼當作核心而把資料結構當作

對代碼的支援,結果是代碼非常漂亮但是資料結構設計得很特别,相當醜陋(至少

對以這個老LISP黑客的标準來看),然而除了提高代碼和資料結構設計之外,重寫

它還有一個目的,就是要把它演化為我徹底了解的東西,對修改你不了解的程式

中的錯誤負責可不是一件有趣的事。

  第一個月我隻是在領會Carl's的基本設計的含義,我所做的第一個重大修改

是加入了IMAP支援,我把協定機重新組織為一個通用驅動程式和三個方法表(對應

POP2、POP3和IMAP),這個前面的修改指出一個需要程式員(特别是象C這種沒有自

然的動态類型支援的語言)記在腦中的一般原理:

 9. 聰明的資料結構和笨拙的代碼要比相反的搭配工作的更好

  Fred Brooks也在他第11章中講道:“讓我看你的[代碼],把你的[資料結

構]隐藏起來,我還是會迷惑;讓我看看你的[資料結構],那我就不需要你的[代

碼]了,它是顯而易見的”。

  實際上,他說的是“流程圖”和“表”,但是在三十年的術語/文化演進之

後,事情還是一樣的。

  此時(1996年9月初,在從零開始六個月後),我開始想接下來修改名字——畢

竟,它已不僅僅是一個POP客戶,但我猶豫了,因為還沒有什麼新的漂亮設計呢,

我的popclient版本需要有自己的特色。

  當fetehmail學會怎樣把取到的郵件轉送到SMTP端口時,事情就完全改變了,

但是首先:上面我說過我決定使用這個工程來測試我關于Linus Torualds所做的

行為的理論,(你可能會問)我怎樣做到這點呢? 以下面的方式:

 1. 我盡早盡量頻繁的釋出(幾乎從未少于每十天釋出一次;在密集開發的時候

是每天一次)。

 2. 我把每一個和我讨論fetchmail的人加入一個beta表中。

 3. 每當我釋出我都向beta表中的人發出通告,鼓勵人們參與。

 4. 我聽取beta測試員的意見,向他們詢問設計決策,對他們寄來的更新檔和回報

表示感謝。

  這些簡單的手段立即收到的回報,在工程的開始,我收到了一些錯誤報告,

其品質足以使開發者是以被殺掉,而且經常還附有更新檔、我得到了理智的批評,

有趣的郵件,和聰明的特征建議,這導緻了:

 10. 如果你象對待最寶貴的資源一樣對待你的beta測試員,他們就會成為你最

寶貴的資源。

六. popclient變成了Fetchmail

  這個工程的真正轉折點是Harry Hochleiser寄給我他寫的代碼草稿,他把郵

件轉發到用戶端機器的SMTP端口,我立即意識到這個特征的可靠實作将淘汰所有

其他的遞送模式。

  幾個星期以來我一直在修改而不是改進fetchmail,因為我覺得界面設計雖然

有用但是太笨拙瑣碎了,到處充滿了太多的粗陋的細小選項。

  當我思考SMTP轉發時我發現popclient試圖做的事太多了,它被設計成既是一

個郵件傳輸代理(MTA)也是一個本地遞送代理(MDA)。使用SMTP轉發,它就可以從

MDA的事務中解脫出來而成為一個純MTA,而象sendmail一樣把郵件交給本地遞送

程式來處理。

  既然端口25在所有支撐TCP/IP的平台上早已被預留,為什麼還要為一個郵件

傳輸代理的配置或為一個郵箱設定加鎖的附加功能而操心呢?尤其是當這意味着抽

取的郵件就象一個正常的發送者發出的SMTP郵件一樣,而這就是我們需要的。

  這裡有幾個教益:第一,SMTP轉發的想法是我有意識地模拟Linus的方法以來

的最大的單個回報,一個使用者告訴我這個非同尋常的想法——我所需做的隻是理

解它的含義。

 11. 想出好主意是好事,從你的使用者那裡發現好主意也是好事,有時候後者更

好。

  很有趣的是,你很快将發現,如果你完全承認你從其他人那裡得到多少教益

的話,整個世界将會認為所有的發明都是你做出的,而你會對你的天才變得謙

虛。我們可以看到這在Linus身上展現得多明顯!(當我在1997年8月的Perl會議上

發表這個論文時,Larry Wall坐在前排,當我講到上面的觀點時,他激動的叫了

出來:“對了!說對了!哥們!”所有的聽衆都哄堂大笑起來,因為他們知道同樣的

事情也發生在Perl的發明者身上)。

  于是在同樣精神指導下工程進行了幾個星期,我開始不光從我的使用者那兒也

從聽說我的系統的人那兒得到類似的贊揚,我把一些這種郵件收藏起來,我将在

我開始懷疑自己的生命是否有價值時重新讀讀這些信。:)

  但是有兩個更基本的,非政治性的對所有設計都有普遍意義的教益。

 12. 最重要和最有創新的解決方案常常來自于你認識到你對問題的概念是錯誤

的。

  一個衡量fetchmail成功的有趣方式是工程的beta測試人員表(fegtchmail的

朋友們)的長度,在創立它的時候已經有249個成員了,而且每個星期增加兩到三

個。

  實際上,當我在1997年5月校訂它時,這張表開始因為一個有趣的原因而縮短

了,有幾個人請求我把他們從表中去掉,因為fetchmail已經工作的如此之好,他

們不需要看到這些郵件了!也許這是一個成熟的市集風格工程的生命周期的一部分。

  我以前一直在解決錯誤的問題,把popclient當作MTA和具有許多本地遞送模

式的MDA的結合物,Fetchmail的設計需要從頭考慮為一個純的MTA,做為一個普通

Internet郵件路徑的一部分。

  當你在開發中碰了壁時(當你發現自己很難想通下一步時),那通常不是要問

自己是否找到正确答案,而是要問是否問了正确問題,也許需要重新構造問題。

  于是,我重新構造了我的問題,很清楚,要做的正确的事是(1)把SMTP轉發支

持放在通用驅動程式中,(2)把它做為預設模式,(3)最終分離所有其他的遞送模

式,尤其是遞送到檔案和标準輸出的選項。

  我在第三步上猶豫了一下,擔心會讓popdiant的長期使用者對新的遞送方法感

到煩心,在理論上,他們可以立即轉而轉發檔案或者他們的非sendmail等價物來

得到同樣的效果,在實際中這種轉換可能會很麻煩。

但是當我這麼做之後,證明好處是巨大的,驅動程式代碼的備援的部分消失

了,配置完全變得簡單了——不用屈從于系統MDA和使用者的郵箱,也不用為下層

OS是否支援檔案鎖定而擔心了。

  而且,丢失郵件的唯一漏洞也被堵死了,如果你選擇了遞送到一個檔案而磁

盤已滿,你的郵件就會丢失,這在SMTP轉發中不會發生,因為SMTP偵聽器不會返

回OK的,除非郵件可以遞送成功或至少被緩沖留待以後遞送。

  還有,性能也改善了(雖然在單次執行中你不會注意到),這個修改的另一個

不可忽視的好處是手冊變得大大簡單了。

  後來,為了允許處理一些罕見的情況,包括動态SLIP,我必須回到讓使用者定

義本地MDA遞送上來,但是我發現了一個更加簡單的方法。

  所有這些給了我們什麼啟發呢?如果可以不損失效率,就要毫不猶豫抛棄陳舊

的特性,Antonine de Saint-Exupery(在他成為經典兒童書籍作家之前是一個飛

行員和飛機設計師)曾說過:

 13. “最好的設計不是再也沒有什麼東西可以添加了,而是再也沒有什麼東西

可以去掉。”

  當你的代碼變得更好和更簡單時,這就是你知道它是正确的時候了,而且在

這個過程中,fetehmail的設計具有了自己的特點,而差別于其前身popclient。

  現在是改名的時候了,這個新的設計看起來比老popclient更象一個sendmail

的複制品,它們都是MTA,但是Senmail是推然後遞送,而新的popclient是拉然後

遞送。于是,在兩個月之後,我把它重新命名為fetehmail。

 七. Fetchmail成長起來

  現在我有了一個簡潔和富有創意的設計,工作得很好的代碼,因為我每天都

用它,和一直在增長的beta表,它讓我漸漸明白我已經不是在從事隻能對少數其

他人有用的工作中,我寫了一個所有有一個Unix郵箱和SLIP/PPP郵件連接配接的人都

真正需要的程式。

  通過SMTP轉發功能,它成為一個潛在的“目錄殺手”,遠遠領先于它的競争

者,這個程式如此能幹以至于其他的程式不但被放棄簡直被忘記了。

  我知道你不可以真得瞄準或計劃出這樣的結果,你隻能努力去設計這些強大

的思想,以後這些結果就好象是不可避免的、自然的、注定了的,得到這種思想

的唯一辦法是擷取許多思想,或者用工程化的思考其他人的好主意而超過原來想

到它的人的設想。

  Andrew Tanenbanm原來設想建造一個适合386的簡單的Unix用做教學,Linus

Torvalels把Andrew的可能想到的Minix可以做什麼的概念推進了一步,成長為一

個極好的東西,同樣的(雖然規模較小),我接受了Card Harris和Harry

Hochheiser的想法,把它們變得更強大,我們都不是人們所浪漫幻想的天才的創

始人,但是大多數科學和工程和軟體開發不是被天才的創始人完成的,這和流傳

的神話恰恰相反。

結果總是執着的原因——實際上,它是每個黑客為之生存的成功!而且它們意

味着我必須把自己的标準定高一點,為了把fetchmail變得和我所能設想的那樣

好,我必須不僅為我自己的需要寫代碼,而且也要包括對在我生活圍首頁外的人

們的需求的支援,而且同時也要保證程式的簡單和健壯。

  在實作它之後我首先寫的最重要的特征是支援多投——從集中一組使用者的郵

件的郵箱中取出郵件,然後把它路由到每個人手中。

  我之是以加上多投功能部分是因為有些使用者一直在鬧着要它,更是因為我想

它可以從單投的代碼中揭露出錯誤來,讓我完全一般地處理尋址,而且這被證明

了。正确解釋RFC822花了我相當長的時間,不僅因為它的每個單獨部分都很難,

而且因為它有一大堆互相依賴的苛刻的細節。

  但是多投尋址也成為一個極好的設計決策,由此我知道:

14. 任何工具都應該能以預想的方式使用,但是一個偉大的工具提供你沒料到

的功能。

  Fetchmant多投功能的一個沒有料到的用途是在SLIP/PPP的用戶端提供郵件

清單、别名擴充。這意味着一個使用個人機器的人不必持續通路ISP的别名檔案就

能通過一個ISP帳戶管理一個郵件清單。我的beta測試員提出的另一個重要的改變

是支援8位MIME操作,這很容易做,因為我已經仔細的保證了8位代碼的清晰,不

僅因為我預見到了這個特性的需求,而且因為我忠實于另一準則:

 15. 當寫任何種類的網關型程式時,多費點力,盡量少幹擾資料流,永遠不要

抛棄資訊,除非接收方強迫這麼作!

  如果我不遵從這個準則,那麼8位MIME支援将會變得困難和笨拙,現在我所需

要做的,是隻讀一下RFC 1652,在産生信頭的邏輯加上一點而已。

  一些歐洲使用者要求我加上一個選項來限制每次會話取得消息數(這樣他們就可

以從昂貴的電話網中控制花費了),我很長一段時間拒絕這樣做,而且我仍然對它

不很高興,但是如果你是為了世界而寫代碼,你必須聽取顧客的意見——這并不

随他們不付給你錢而改變。

八. 從Fetchmail得來的另一些教益

  在他們回到一般的軟體工程問題以前,還有幾個從fetchmail得到的教益需要

思考。

  rc檔案文法包括可選的“noise”關鍵字,它被掃描器完全忽略了,當你把它

們全抽取出的時候,關鍵字/值對更具可讀性。

  當我注意到rc檔案的聲明在多大程度上開始象一個微型指令語言時,這是一個

Late-night的體驗(這也是我為什麼把popclient原來的“server”關鍵字改成了

“poll”)。

  對我來說似乎把這個微型指令語言變得更象英語可能會使它更容易使用。現在,

雖然我對經過Emacs和HTML及許多資料庫引擎所證明的“把它做成一個語言”的設計

方式确信不疑,但是我并不是一個通常的“類英語”文法的狂熱擁護者。

  傳統程式員容易控制文法使它盡量精确和緊湊,完全沒有備援,這是計算機資

源還很昂貴時遺留下的一種文化傳統,是以掃描政策需要盡可能的廉價和簡單,而

具有50%備援度的英語,看來好象是一個非常不合适的模型。

  這并不是我不用類英語文法的原因,我提到這一點是為了推翻它,在更廉價的

時鐘周期與核心的時代,簡潔并沒有走到盡頭,今天對一個語言來說,對人更友善

比對機器更廉價來的更加重要。

  然而,有幾個原因提醒我們小心一點,一個是掃描政策的複雜度開銷——你并

不想把它變成一個巨大的錯誤來源和讓使用者困惑,另一個是試圖使語言表面上的類

似可以和傳統語言一樣令人困惑(你可以在許多4GL和商業資料庫查詢語言上看到這

一點)。

  Fetchmail的控制文法避免了這些問題,因為語言的領域是極其有限的。它一

點也不象一個一般性的語言,它很簡單地描述的東西并不複雜,是以很少可能在英

語的一個小子集與實際的控制語言之間發生混淆,我想這有一個更廣泛的教益:

 16. 如果你的語言一點也不象是圖靈完備的,嚴格的文法會有好處。

  另一個教益是關于安全的,一些fetchmail使用者要求我修改軟體把密碼加密存

貯在rc檔案裡,這樣觑探者就不能看到它們了。

  我沒有這樣做,因為這實際上起不到任何保護作用,任何有權讀取你的rc檔案

的人都可以以你的名義運作fetchmail——如果他們要破你的密碼,它們可以從

fetchmail的代碼中找到制作解碼器的方法。

  是以fetchmail密碼的加密都會給那些不慎重思考的人一種安全的錯覺,這裡

一般性的準則是:

 17. 一個安全系統隻能和它的秘密一樣安全,當心僞安全。

九. 集市風格的必要的先決條件

  本文的早期評審人員和測試人員堅持提出成功的市集模式開發的先決條件,

包括工程上司人的資格問題和在把項目公開和開始建造一個協作開發人員的社團

的時候代碼的狀态。

  相當清楚,不能以一個市集模式從頭開發一個軟體,我們可以以市集模式、

測試、調試和改進,但是以市集模式從頭開始一個項目将是非常困難的,Linus

沒有這樣做,我也沒有,初期的開發人員的社團應該有一此可以運作和測試的

東西來玩。

  當你開始建立社團時,你需要示範的是一個諾言,你的程式不需要工作的

很好,它可以很粗糙、很笨拙、不完整和缺少文檔、它不能忽略的東西是要吸

引哪些人卷入一個整潔的項目。

  Linux和fetchmail都是以一個吸引人的基本設計進入公共領域的,許多和

我一樣在思考市集模式的人已經正确的認為這是非常關鍵的,然後得出了一個

結論,工程上司者的高度的設計直覺和聰穎是必不可少的。

  但是Linus是從Unix得到他的設計的,我最初是從先前的popmail得到啟發的

(雖然相對Linux而言,它最後改變巨大),是以市集風格的上司人/協調人需要有

出衆的設計才能,或者他可以利用别人的設計才能?

  我認為能夠提出卓越的原始設計思想對協調人來說不是最關鍵的,但是對

他/她來說絕對關鍵的是要能把從他人那裡得到的好的設計重新組織起來。

  Linux和fetchmail項目都顯示了這些證據,Linus(如同前面所說)并不是驚人

的原始設計者,但他顯示了發現好的設計并把它內建到Linux核心中的強大決竅。

還有我也描述了怎樣從别人那裡得到了fetchmail中最強大的設計思想(SMTP轉發)。

  本文的早期讀者稱贊我,說因為我做了許多關于原始設計的事,是以傾向于

低估原始設計在市集項目中的價值,也許有些是對的吧,但是設計(而不是編碼或

調試)本來就是我最強的能力。

  變得聰明和軟體設計的原始創作的問題是它會變成一個習慣,當需要保持事

物健壯和簡潔的時候,你卻開始把事情變得漂亮但卻複雜。我曾經犯過錯誤,使

得一些項目因我而崩潰了,但我努力不讓它發生在fetchmail身上。

  是以我相信fetchmail項目的成功部分是因為我抑制自己不要變得太聰明,這

說明(至少)對市集模式而言原始設計并不是本質的,請考察一下Linux假設Linus

Torvalds在開發時試圖徹底革新作業系統設計,它還會象今天我們所擁有的核心

那樣穩定和成功嗎?

  當然基本的設計和編碼技巧還是必需的,但我希望每個嚴肅考慮發起一個市

集計劃的人都已至少具備這些能力,自由軟體社團的内部市場對人們有某些微妙

的壓力,讓他們不要發起自由不能搞定的開發,目前為止,這工作得仍然相當好。

  對市集項目來說,我認為還有另一種通常與軟體開發無關的技能和設計能力

同樣重要——或者更加重要,市集項目的協調人或上司人必須有良好的人際和交

流能力。

  這是很顯然的,為了建造一個開發社團,你需要吸引人,你所做的東西要讓

他們感到有趣,而且要保持他們對他們正在做的工作感到有趣,而且要保持他們

對他們正在做的工作感到高興,技術方面對達成這些目标有一定幫助,但這遠遠

不是全部,你的個人素質也有關系。

  并不是說Linus是一個好小夥子,讓人們喜愛并樂于幫助他,也并不是說我是

個積極外向的,喜歡紮堆兒工作,有出衆的幽默感的人,對市集模式的工作而

言,至少有一點吸引人的技巧是非常有幫助的。

十. 自由軟體的社會學語境

 下述如實:最好的開發是從作者解決每天工作中的個人問題開始的,因為它

對一大類使用者來說是一個典型問題,是以它就推廣開來了,這把我們帶回到準則1,

也許是用一個更有用的方式來描述:

 18. 要解決一個有趣的問題,請從發現讓你感興趣的問題開始。

  這是Carl Harris和原先的popclient的情形,也是我和fetchmail的情形,但

這已在很長一段時間被大家知曉了,Linux和fetchmail的曆史要求我們注意的有

趣之處是下一個階段——軟體在一個龐大的活躍的使用者和協作開發人員的社團中

的進化。

  在《神秘的人月》一書中,Fred Brooks觀察到程式員的工作時間是不可替代

的:在一個誤了工期的軟體項目中增加開發人員隻會讓它拖得更久,他聲稱項目

的複雜度和通訊開銷以開發人員的平方增長,而工作成績隻是以線性增長,這個

說法被稱為“Brooks定律”,被普遍當作真理,但如果Brooks定律就是全部,那

Linux就不可能成功。

  幾年之後,Gerald Weinbeng的經典之作“The Psychology Of Computer

Progromming”為我們更正了Brooks的看法,在他的“忘我(egoless)的程式設計”中,

Weinberg觀察到在開發人員不頑固保守自己的代碼,鼓勵其他人尋找錯誤和發展

潛力的地方,軟體的改進的速度會比其他地方有戲劇性的提高。

  Weinberg的用詞可阻止了他的分析得到應有的接受,人們對把Internet黑客

稱為“忘我”的想法微笑,但是我想今天他的想法比以往任何時候都要引人注目。

  Unix的曆史已經為我們準備好了我們正在從Linux學到的(和我在更小規模上

模仿Linus的方法所驗證的)東西,這就是,雖然編碼仍是一個人幹的活,真正偉

大的工作來自于利用整個社團的注意和腦力,在一個封閉的項目中隻利用他自己

的腦力的人會落在知道怎樣建立一個開放的、進化的,成百上千的人在其中查找

錯誤和進行修改的環境的開發人員之後。

  但是Unix的傳統中有幾個因素阻止把這種方法推到極緻。一個是各種授權的

法律限制、商業機密和商業利益,另一個(事後來看)是Internet還不夠好。

  在Internet變得便宜之前,有一些在地理上緊密的社團,

——摘自:http://www.tuxedo.org/~esr

繼續閱讀