# 二十七、程序設計界的LordPalmerston
曾經一度如果讀過Peter Norton的一本書,就能完全了解在IBM-PC上寫程序所需 的全部知識。在過去20年間,全世界的程序員很努力地在IBM-PC上建立層層的抽 象機制,讓程序更容易撰寫而且功能更強大。
不過抽象滲漏法則表示,即使他們建立了這些理應讓程序更易設計的抽象機制, 做個偉大的程序員所需的各種知識還是一直在增加。
要真正地精通某個程序設計領域需要好幾年的工夫。當然也有很多出色的青少年 學了一星期Delphi,再學一星期Python然后再學一個星期的Perl,就自認已經精 通了。不過他們根本不知道自己差得有多遠。
我打從ASP和VBScript剛出來就在用了。VBScr i pt是世界上最微不足道的程序語 言,而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才發生的怪問題時,我只花了三分鐘就解決了, 因為我知道如何使用VMWa「e,而且我有一套用VMWa「e灌的干凈NT4.0機器,另外 我也知道如何用Visual C++做遠程除錯,還知道可以由EAX緩存器知道函數的回 傳值。完全沒接觸過這些東西的人要抓同一個問題,恐怕得花一個小時或更多的 時間,不過我已經知道了很多很多「東西」,那些基本上是從1982年拿到我第 一臺IBM-PC和那本Norton書時就開始學的東西。
有漏洞的抽象表示我們面對一個直線上升的學習曲線:你可以用一星期學到每天 工作所需知識的90%。不過其他10%可能得要好幾年才能補齊。有些人會說:「不 管你要我做什么,我都可以拿本書來就學會了。」真正有經驗的程序員超越這種 人的地方就在這里。如果你正在建立一個團隊,當然可以找一堆經驗較少的程 序員用抽象工具制作出一大堆程序代碼,不過如果少了經驗老到的人去做真正困 難的事情,這個團隊是做不起來的。
程序設計有很多不同的世界,每個世界都需要大量的知識才能真正的精通。以下 是我個人最熟的三個領域:
1. MFC/C++/Windows
2. VBScript/ASP
3. Visual Basic
基本上這全部都可以稱作Windows程序設計。沒錯,我也寫過Unix或Java的程序, 不過很少就是了。我對Windows程序設計的專精不光是了解基本技術,也知道整 個支持的整體結構。我敢宣稱對Windows程序設計很在行,是因為我也會COM、ATL、 C++、80x86 匯編語言、Windows API、IDispatch (OLE Automation)、HTML、DOM、 Internet Exp lore「對象模式,Windows NT以及 Windows 95 內部機制,LAN Manager 和NT網絡以相關安全機制(ACE、ACL等等)、SQL及SQL Server、Jet和Access、 JavaScript、XML,還有一些其他有關直角三角形斜邊的有趣事實。如果不能在 VB里用StrConv函數達成我的目的,我會為了用C++和ATL呼叫MLang函數而去寫一 個COM控制組件,眼睛連眨都不會眨一下。我花了很多年才達到這種境界。
還有很多其他程序設計的世界。有開發BEA Web log i c的世界,里頭的人要懂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)存各個名稱/值的組合,不 過你有上千種不同的文件格式,每種應用程序都各有一種,而且到處都有.「c和 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+SpaceN把窗口縮到最小」都可以在Mozilla里面使用;雖然花了很久不過他 們還是做到了。
成立Lotus并創造123的Mitch Kapor決定下一個計劃要做一個叫wxWindows和 wxPython的產品,目標也是跨平臺支持。
哪一個比較好呢?是XUL?是Eclipse的SWT?還是wxWindows呢?我不知道。這些 都是很龐大的世界,大到我根本無法實際去評估并找出答案。光是讀完教學并 不夠。你必須自己去辛苦用個一兩年,才能真正知道它是的確夠好,還是怎么試 都無法讓做出感覺對勁的使用接口。不幸的是,大多數項目都必須在寫第一行 程序之前決定要用哪個世界,而這正是信息最少的時候。在前一個工作我們得面 對某些很爛的架構,因為最早期的程序員利用該項目同時學寫C++和Windows程 序設計。有些最初期的程序代碼是完全不懂事件驅動程序設計下寫出來的。核心 的字符串類別(我們當然有自己的字符串類別)可以寫進教科書,用以示范C++
類別在設計上會犯的各種錯誤。最后終于把很多舊程序清理并重整干凈,不過還 是讓我們頭痛了好一陣子。
所以現在我會建議:至少要有一個對所用的語言、類別、API以及平臺有數年以 上經驗的設計者,否則還是不要啟動項目吧。如果你可以選擇平臺,就用你的 團體最熟悉的吧,即使這個平臺并不是最符合趨勢或看起來最有生產力也沒關系。 另外在設計抽象機制或程序設計工具時,多做些努力讓它不會漏吧。
- 第一部分 位與字節:編程實踐點滴
- 一、語言的選擇
- 二、深入底層
- 三、joel測試:改進代碼的12個步驟
- 四、每一位軟件開發人員必須、絕對要至少具備UNICODE 與字符集知識(沒有任何例外!)
- 五、輕松寫就功能規格說明書 - 第1節:為什么煩心?
- 六、輕松寫就功能規格說明書 - 第2節:什么是規格說明書?
- 七、輕松寫就功能規格說明書 - 第3節:但是……如何?
- 八、輕松寫就功能規格說明書 - 第4節:技巧
- 九、輕松制訂軟件進度表
- 十、每日連編是朋友
- 十一、難伺候的故障修復
- 十二、軟件開發中的5個世界
- 十三、稿紙原型開發
- 十四、不要被太空架構師所嚇倒
- 十五、開火與運動
- 十六、人員技能
- 十七、源于計算機學科的三個錯誤思想
- 十八、二元文化
- 十九、自動獲取用戶故障報表
- 第二部分 開發人員的管理
- 二十、面試游擊指南
- 二十一、重金激勵害多利少
- 二十、二不配備測試人員的五個首要(錯誤)原因
- 二十三、任務換人有害無益
- 二十四、絕不去做的事情,第一部
- 二十五、冰川下的秘密
- 二十六、漏洞抽象定律
- 二十七、程序設計界的LordPalmerston
- 二十八、評測
- 第三部分 Joel對常態問題的遐想
- 二十九、RickChapman解讀愚昧
- 三十、在這個國家狗是干什么的? 我們有多么天真?
- 三十一、作為哼哈二將,只管去做事
- 三十二、兩個故事
- 三十三、巨無霸麥當勞與天才廚師JamieOliver
- 三十四、沒有什么像IT看起來那么簡單
- 三十五、提防非自主開發綜合癥
- 三十六、策略I:BEN&JERRY公司與AMAZON
- 三十七、策略II:雞與蛋問題
- 三十八、策略III:讓我回去!
- 三十九、策略IV:大件與80/20神話
- 四十、策略V:公開源代碼的經濟因素
- 四十一、墨菲法則肆掠的禮拜
- 四十二、微軟公司是如何敗北API之戰的
- 第四部分 對.NET稍多的評說
- 四十三、微軟精神失常了
- 四十四、我們的.NET對策
- 四十五、請問,我可以使用連接程序嗎