程式設計領域的帕麥爾斯頓勳爵

作者:周思博 (Joel Spolsky)
譯:Paul May 梅普華
Wednesday, December 11, 2002
屬於Joel on Software, http://www.joelonsoftware.com


曾經一度如果讀過Peter Norton的一本書,就能完全瞭解在IBM-PC上寫程式所需的全部知識。在過去20年間,全世界的程式師很努力地在IBM-PC上建立層層的抽象機制,讓程式更容易撰寫而且功能更強大。

不過抽象滲漏法則表示,即使他們建立了這些理應讓程式更易設計的抽象機制,做個偉大的程式師所需的各種知識還是一直在增加。

要真正地精通某個程式設計領域需要好幾年的工夫。當然也有很多出色的青少年學了一星期Delphi,再學一星期Python然後再學一個星期的Perl,就自認已經精通了。不過他們根本不知道自己差得有多遠。

我打從ASP和VBScript剛出來就在用了。VBScript是世界上最微不足道的程式語言,而ASP程式設計大概只要上五堂課會了,而且其中只有兩堂是會經常用到的。可是直到現在,我才感覺自已知道架構一個ASP/VBScript應用程式的最佳作法,我才終於覺得自己知道資料庫存取程式最適當的位置,用ADO取得recordset的最佳作法,分離HTML和程式碼的最佳方式等等。另外我也終於會用正規表示式,不再每次都重寫一次字串操作函數。另外我上星期才學會如何取得不在記憶體中的COM物件,這樣就就可以不需整個web伺服器重開就能重新編譯。

Fog Creek太小了養不起專家,所以當我要為FogBUGZ(我們用ASP/VBScript製作的產品)寫一個真正好的安裝程式時,我得拿出數年C++/MFC和Windows API的經驗,再用我還不錯的Corel PhotoPaint技巧做出放在精靈角落的圖片。另外為了讓FogBUGZ能無誤地使用Unicode,我還得用C++和ATL寫一個小小的ActiveX元件,這裡頭有著數年的C++和COM經驗,還有當初實作CityDesk時學了一週左右的字元編碼知識。

所以當我們遇到某個只有NT 4.0才發生的怪問題時,我只花了三分鐘就解決了,因為我知道如何使用VMWare,而且我有一套用VMWare灌的乾淨NT 4.0機器,另外我也知道如何用Visual C++做遠端除錯,還知道可以由EAX暫存器知道函數的回傳值。完全沒接觸過這些東西的人要抓同一個問題,恐怕得花一個小時或更多的時間,不過我已經知道了很多很多「東西」,那些基本上是從1982年拿到我第一台IBM-PC和那本Norton書時就開始學的東西。

有漏洞的抽象表示我們面對一個直線上升的學習曲線:你可以用一星期學到每天工作所需知識的90%。不過其他10%可能得要好幾年才能補齊。有些人會說:「不管你要我做什麼,我都可以拿本書來就學會了。」真正有經驗的程式師超越這種人的地方就在這裡。如果你正在建立一個團隊,當然可以找一堆經驗較少的程式師用抽象工具製作出一大堆程式碼,不過如果少了經驗老到的人去做真正困難的事情,這個團隊是做不起來的。

程式設計有很多不同的世界,每個世界都需要大量的知識才能真正的精通。以下是我個人最熟的三個領域:

基本上這全部都可以稱作Windows程式設計。沒錯,我也寫過Unix或Java的程式,不過很少就是了。我對Windows程式設計的專精不光是瞭解基本技術,也知道整個支援的整體結構。我敢宣稱對Windows程式設計很在行,是因為我也會COM、ATL、C++、80x86 組合語言、Windows API、IDispatch (OLE Automation)、HTML、DOM、Internet Explorer物件模式,Windows NT以及Windows 95內部機制,LAN Manager和NT網路以相關安全機制(ACE、ACL等等)、SQL及SQL Server、Jet和Access、JavaScript、XML,還有一些其他有關直角三角形斜邊的有趣事實。如果不能在VB裡用StrConv函數達成我的目的,我會為了用C++和ATL呼叫MLang函數而去寫一個COM控制元件,眼睛連眨都不會眨一下。我花了很多年才達到這種境界。

還有很多其他程式設計的世界。有開發BEA Weblogic的世界,裡頭的人要懂J2EE、Oracle還有各種我列不出來跟Java相關的東西。另外也有硬派的麥金塔開發者,他們懂的是CodeWarrior、MPW、由System 6到OS/X各版本的Toolbox程式設計、Cocoa、Carbon、甚至還有現在已經沒用的OpenDoc等過時的好東西。

不過只有極少數人能清楚一個以上的世界,因為要學的實在太多,除非在這些世界工作過幾年,否則是不會真的全部都懂。

不過你卻必須學會。

面試時因為沒有Win32或是J2EE或Mac程式設計經驗而被拒絕,大家都會覺得很生氣。 或者某些笨蛋面試官其實根本不知道MSMQ,卻打電話問面試者是否具有「五年的MSMQ經驗」,也會讓人覺得很不爽。

如果你剛寫Windows程式不久,你可能認為Win32只不過是個程式庫,跟其他程式庫差不多,要用到時再去查書學著怎麼呼叫就好了。你可能會認為基本的程式設計(比如你的C++專業技能)佔九成,所有API合起來算是只佔一成的小事,幾星期就可以惡補回來。對這些人我只能小聲地建議:時代已經變了。現在的比例是反過來的。

已經很少有人需要去做把位元組搬來搬去的低階C演算法了。現在我們大多數人都把全部時間花在呼叫API而不是搬移位元組。一個沒有API經驗的C++程式高手,對用API寫程式的日常工作內容其實只知道大約一成而已。當經濟狀況好的時候這並不打緊。你還是會得到工作,而雇主會花錢讓你熟悉平台。不過當經濟不景氣時,每個工作都有600個人申請,雇主有本錢選擇已經精通該平台的程式師。比如說能列出四種Visual Basic中FTP檔案的方法,還能指出每種方法優缺點的人。

這所有的程式設計世界的表相都很多,因此常常引發毫無意義的論戰,爭執哪個世界比較好。某位匿名者在我的討論區寫了以下這段自以為是的意見:

「再說另一個讓我樂意留在『自由世界』的理由,言辭的自由(幾乎),以及免於屈從安裝程式和registry這種東西(還有很多,我只是舉兩個例子)的自由。」

我認為這個人真正要說的是,在Linux世界裡是不寫安裝程式的。嗯,我討厭讓你失望,不過你的世界也有些一樣麻煩的東西:imake、make、config檔等玩意。另外當你完成應用程式之後,要發行時還得附上20KB的INSTALL檔案,裡頭全是些拿古怪裝有趣的指示,比如「你會需要zlib」(那是什麼東西?)或是「這會要花一些時間,去拿一些runt吧。」 (我猜runt大概是某種糖果吧)。至於registry登錄檔,雖然你並沒有用一個有組織的大結構(hive)存各個名稱/值的組合,不過你有上千種不同的檔案格式,每種應用程式都各有一種,而且到處都有.rc和foo.conf檔案。另外想在emacs裡更改設定還得學寫lisp程式,而每個shell都要你學它獨有的shell腳本方言才能更改設定,還有其他其他其他。

只認識一個世界的人是很討人厭的。他們每次聽到其他世界的複雜狀況時,就會覺得自己的世界沒那麼複雜。不過事實上是一樣的。只是你已經很精通,所以視而不見。這些世界實在太大太複雜無法相互比較。帕麥爾斯頓勳爵(Lord Palmerston)說過:「什列斯威-好斯敦問題(Schleswig-Holstein Question)問題實在是太複雜了,整個歐洲也只有三個人瞭解。第一位是已經逝世的Prince Albert。第二位是某個瘋了的德國教授。第三位就是我,不過我已經完全忘掉了。」軟體的世界也是如此巨大複雜而多面相,以致當我看到某些其方面很聰明的人在網誌寫些像「微軟不懂作業系統」之類的空話時,不禁要坦白的說他們看起來很蠢。Windows是由數百位程式師在十到廿年間所創造,具有數百個功能的幾百萬行程式。想像嘗試要概述這種龐然大物,卻連開始瞭解其中一大部份就沒有。我並不是在為微軟辯護,只是覺得這種源自極度無知的巨大模糊概括,是現在網路上最浪費時間的東西。

常來的讀者應該已經注意到我在思考要如何發展跨Linux、Macintosh和Windows平台的應用程式,又不必為Linux和Macintosh版本投入不成比例的成本。這時候你需要某種跨平台程式庫。

Java有這個野心,不過Sun並沒有真的把GUI弄通,不能做出真正感覺自然的應用程式。這就像星艦迷航記裡的太空異形透過望遠鏡觀察地球一樣,他們知道人類食物的外觀,卻不瞭解它的味道。Java程式會在正確的地方畫出功能表,可是鍵盤操作和Windows程式完全不一樣,而且Java的分頁對話盒看起來有點恐怖。另外不管怎麼試都不能讓功能表列和Excel的一模一樣。為什麼會這樣呢?因為Java在抽象機制失敗時,並沒有提供很好的方法去將就使用平台原始的機制。當你用AWT寫程式時並不能取得視窗的HWND,不能呼叫微軟的API,當然也不能把WM_PAINT攔截起來自己畫。而Sun已經表示得很明白了,如果你這樣就就不夠純粹。你被污染了所以活該去死。

試圖用Java建立GUI的努力經過多次眾所周知的失敗之後(比如Corel的Java Office suite和Netscape的Javagator),不少人學會要和這個世界保持距離。Eclipse運用平台原本的機制,從最底層開始建立了他們自己的視窗程式庫,這樣才能寫出使用觀感符合原平台感覺的Java程式。

Mozilla的工程師決定用他們自己的發明XUL來處理跨平台問題。到目前為止令我印象深刻。Mozilla終於做到用起來感覺對勁的境界。連我最喜歡的怪用法「用Alt+Space N把視窗縮到最小」都可以在Mozilla裡面使用;雖然花了很久不過他們還是做到了。

成立Lotus並創造123的Mitch Kapor決定下一個計劃要做一個叫wxWindows和wxPython的產品,目標也是跨平台支援。

哪一個比較好呢?是XUL?是Eclipse的SWT?還是wxWindows呢?我不知道。這些都是很龐大的世界,大到我根本無法實際去評估並找出答案。光是讀完教學並不夠。你必須自己去辛苦用個一兩年,才能真正知道它是的確夠好,還是怎麼試都無法讓做出感覺對勁的使用介面。不幸的是,大多數專案都必須在寫第一行程式之前決定要用哪個世界,而這正是資訊最少的時候。在前一個工作我們得面對某些很爛的架構,因為最早期的程式師利用該專案同時學寫C++和Windows程式設計。有些最初期的程式碼是完全不懂事件驅動程式設計下寫出來的。核心的字串類別(我們當然有自己的字串類別)可以寫進教科書,用以示範C++類別在設計上會犯的各種錯誤。最後終於把很多舊程式清理並重整乾淨,不過還是讓我們頭痛了好一陣子。

所以現在我會建議:至少要有一個對所用的語言、類別、API以及平台有數年以上經驗的設計者,否則還是不要啟動專案吧。如果你可以選擇平台,就用你的團體最熟悉的吧,即使這個平台並不是最符合趨勢或看起來最有生產力也沒關係。另外在設計抽象機制或程式設計工具時,多做些努力讓它不會漏吧。

 

這些網頁的內容為表達個人意見。
All contents Copyright © 1999-2006 by Joel Spolsky. All Rights Reserved.