Anders Hejlsberg訪談:Checked Exceptions的問題

本訪談系列的翻譯已經徵得原作者的同意,轉載請保留原作者和譯者的鏈接。

Copyright © 1996-2005 Artima Software, Inc. All rights reserved

The Trouble with Checked Exceptions
A Conversation with Anders Hejlsberg, Part II
by Bill Venners with Bruce Eckel
August 18, 2003

Checked Exceptions的問題

翻譯:劉曉偉

摘要
Anders Hejlsberg
C#的主架構師,與Bruce EckelBill Venners談論了已檢測異常(checked exceptions)的版本(versionability)問題和可伸縮性(scalability)問題。

Anders Hejlsberg,微軟的一位傑出工程師,他領導了C#(發音是C Sharp)編程語言的設計團隊。Hejlsberg首次躍上軟件業界舞臺是源於他在80年代早期爲MS-DOSCP/M寫的一個Pascal編譯器。不久一個叫做Borland的非常年輕的公司僱傭了他並且買下了他的編譯器,從那以後這個編譯器就作爲Turbo Pascal在市場上推廣。在BorlandHejlsberg繼續開發Turbo Pacal並且在後來領導一個團隊設計Turbo Pascal的替代品:Delphi1996年,在Borland工作13年以後,Hejlsberg加入了微軟,在那裏一開始作爲Visual J++windows基礎類庫(WFC)的架構師。隨後,Hejlsberg擔任了C#的主要設計者和.NET框架創建過程中的一個主要參與者。現在,Anders Hejlsberg領導C#編程語言的後續開發。

2003730號,Bruce Eckel(《Thinking in C++》以及《Thinking in Java》的作者)和Bill VennersArtima.com的主編)與Anders Hejlsberg在他位於華盛頓州Redmond的微軟辦公室進行了一次面談。這次訪談的內容將分多次發佈在Artima.com以及Bruce Eckel將於今年秋天發佈的一張音頻光碟上。在這次訪談中,Anders Hejlsberg談論了C#語言和.NET框架設計上的一些取捨。

  • 第一部分:C#的設計過程中, Hejlsberg談論了C#設計團隊所採用的流程,以及在語言設計中可用性研究(usability studies)和好的品味(good taste)相對而言的優點。

  • 在第二部分裏,Hejlsberg談論了已檢測異常(checked exceptions)的版本(versionability)問題和可伸縮性(scalability)問題。

對已檢測異常(checked exceptions)保持中立

Bruce Eckel: C#沒有已檢測異常(checked exceptions)。你是如何決定要不要把checked exceptions加入C#的?

Anders Hejlsberg: 我覺得checked exceptions有兩個大問題:可伸縮性(scalability)和版本(versionablility)。我知道你也寫過一些關於checked exceptions的東西,而且你也傾向於我們的看法。

Bruce Eckel: 我曾經以爲checked exceptions是非常棒的。

Anders Hejlsberg: 確切的說,乍看起來它們是非常棒的,這個點子並沒有什麼錯。我完全同意checked exceptions是一個很不錯的特性。可能有問題的只是那些特定的實現。比如,checked exceptionsJava裏的實現方法,我認爲你只是用這一堆問題替代另外一堆問題。最終我還是不清楚你是否真的讓這一切變得更容易了。你只是換湯不換藥罷了。

Bruce Eckel: 關於checked exceptions,在C#的設計團隊裏有很多不同意見嗎?

Anders Hejlsberg: 沒有,我想我們的設計團隊就這個問題在很大程度上是一致的。對於checked exceptions這個問題,C#基本上是保持沉默的。一旦以後有了好的解決方案——相信我,我們還在考慮這件事情——我們會回頭給它添加一些適當的東西。我深信,如果你不知道什麼是正確的,或者不知道前進的方向,那你最好保持沉默和中立,而不是試圖設計一個框架。

如果你要一個編程新手寫一個日曆控件,他們經常會在心中盤算,“哦,我要寫一個世界上最好的日曆控件!它應該根據日曆的類型而展示出多態。它應該有displayersmungers,應該有這個有那個,還應該有其它的東西。”他們需要兩個月才能發佈一個日曆程序。他們把所有這些基礎設施都放到控件裏,然後花兩天時間在它上面寫一個蹩腳的日曆程序。他們想,“下一個版本的程序裏,我會做更多這樣的事情。”

一旦開始考慮如何從實際上實現他們的抽象設計中其它需要具體化的東西,他們就會發現自己的設計徹頭徹尾的錯了。他們把自己把逼進了死衚衕,他們必須把所有的東西都扔掉。我曾經一次又一次地目睹這種事情。我是個極簡主義的信徒。除非你真的要解決通用問題,不要試圖爲了解決一個特定的問題而整出一個框架,因爲你不知道那個框架看起來應該是什麼樣子。

Bruce Eckel: 極限編程的程序員們說,“儘可能地做簡單的事情,能正常運行就可以了。”

Anders Hejlsberg: 是的,愛因斯坦說過,“儘可能地做簡單的事情,但是不要過於簡單。”關於checked exceptions,我所關心的是,它給程序員戴上了手銬。你會看到程序員們撿起這些包含Throws語句的API,然後你會發現他們的代碼有多麼的錯綜複雜,再然後你意識到checked exceptions根本沒有幫上他們什麼忙。這在一定程度上是因爲這些獨斷專行的API設計者告訴你應該如何進行異常處理。他們不應該這麼做。

Checked Exceptions的版本問題

Bill Venners: 你曾經提到了與checked exceptions的可伸縮性(scalability)和版本(versioning)相關的問題。你是否可以就這兩個問題闡明一下您的意思?

 Anders Hejlsberg: 那就讓我們從versioning開始吧,因爲這個問題是顯而易見的。比如說,我創建了一個叫做foo的方法,並且聲明拋出異常ABC。在Foo的第二個版本里,我想要添加一組功能,現在foo可能會拋出異常D。我給那個方法的throws語句添加異常D導致了一個破壞性的變更,因爲那個方法的既有調用者幾乎肯定不會處理這個異常。

throws語句新版本里添加一個新的異常打斷了客戶端代碼。這有點像給一個接口添加一個方法。在你發佈一個接口之後,從實際的角度來說你無論如何都不應該再改動它,因爲它的任何一個實現都有可能包括你在下個版本里想要加入的方法。所以說你最好還是另外創建一個新的接口。異常與此類似,你要麼創建一個全新的方法叫做foo2,讓它拋出更多的異常,要麼你在新的foo版本里捕獲異常D,然後把D轉換成AB或者C中的一個。

Bill Venners: 但是即便是一門不支持checked exceptions的語言,這種情況下你不也是在打斷他們的(客戶端)代碼麼? 如果foo的新版本將要拋出一個新的異常,而客戶端又有必要處理這個異常,但是事實上他們寫代碼的時候並沒有預期到會有這個異常,這不還是要打斷他們的代碼麼?

Anders Hejlsberg: 不,因爲很多情況下人們並不關心(這些異常)。他們原本就沒打算處理這些異常。在消息循環機制中,有一個最底層的異常處理器。這個異常處理器會彈出一個對話框說哪裏出錯瞭然後程序繼續運行。程序員通過書寫try finally語句來保護他們的代碼,這樣當出現異常的時候才能正常退出,但是他們並不真正想要處理這些異常。

至少Java實現throws語句的方法並不強制你處理異常,但是如果你真的不處理它們,它會強制要你明確指出哪些異常可以通過。它會要求你要麼捕獲已經聲明的異常,要麼把它們放進你自己的throws語句。爲了滿足這些條件,人們要做非常荒謬的事情。例如,他們給每個方法都加上,“throws Exceptions”。這恰恰徹底削弱了checked exceptions的特性,你只是讓程序員寫更多羅嗦的廢話。這對誰都沒好處。

Bill Venners: 也就是說你認爲更爲一般的情況是,相對一個通常來說深入調用堆棧的catch語句而言,調用者並不顯示地以不同的方式處理異常?

Anders Hejlsberg: 很有意思的是,人們認爲對於異常來說,重要的事情是如何處理它們。實際上這不是異常最重要的東西。在一個編寫良好的應用程序裏,以我的看法,try finallytry ctach的比例是101或者在C#裏,using staement (譯註:參見《Applied Microsoft .NET Framework Programming》第19) ,它跟try finally很像。

Bill Venners: finally語句裏都有些什麼東西呢?

Anders Hejlsberg: finally語句裏,你保護自己免受exceptions的干擾,但是你並不真正處理它們。錯誤處理會放在其它的地方。在任何類型的事件驅動的程序裏,諸如時髦的UI程序,你通常會圍繞你的主消息循環泵放上一個異常處理器,只有當它們躍出那個範圍你才處理異常。但是要讓自己全身而退你得確信是通過釋放已經佔有的資源等等來達到目的的。誰都不想在一個程序的100個不同地方處理異常並且彈出錯誤對話框。假如說你想要改變一下彈出對話框的方式那可怎麼辦呢?這可糟透了。異常處理應該被集中在一個地方,而且當異常向外傳遞給它的處理程序的時候你只要保護好自己的程序就可以了。

Checked Exceptions的可伸縮性問題

Bill Venners: checked exceptionsscalability問題是指什麼呢?

Anders Hejlsberg: Scalability問題多多少少和版本問題是有關係的。從小的方面來說,checked exceptions是非常有誘惑力的。只要用一個很小的例子,你就能展示給大家說你已經檢驗到捕獲了FileNotFoundException異常,這不很棒麼?是的,當你只是調用一個API的時候這樣做沒有問題。但是當你開始構建大的系統而需要和四五個不同的子系統打交道的時候問題就來了。每個子系統拋出410個異常。現在,每次當你沿着這個聚合而成的階梯往上的時候,你的下面就有了指數級的異常層次(hierarchy),這些異常是你必須要處理的。最終你不得不定義40個可能拋出的異常。一旦你要把這個系統與另外一個子系統聚合在一起,在你的throws語句裏就有了80個異常。異常的數量會失控般的激增。

從大的方面來說,checked exceptions變成了讓人惱火的東西,人們試圖完全繞過這個特性。他們要麼到處寫成,“throws Exception”;要麼——我記不清已經見到過多少次了——寫成,“try, da da da da da, catch curly(花括號) curly(花括號)”他們想,“以後我會回來處理這些空的catch語句”,當然他們再不會回來補上。在這些情況下,從大的方面來講,checked exceptions確實降低了系統的質量。

所以說,當把以上這些問題都考慮在內的話,對我來說,在把類似於checked exceptions的機制加入C#之前,我們可得需要更多的考慮。但是儘管如此,知道哪些異常可以被拋出、以及用一些工作來檢測這些異常,仍然毫無疑問有着巨大的價值。我不認爲我們可以很快構建出牢靠和易用的規則,它要麼是一個編譯錯誤,要麼不是。但是我想我們應當可以就分析工具做一些文章,偵測可疑的代碼,包括未被捕獲的異常,進而爲你指出那些潛在的漏洞。

下週

Anders Hejlsberg訪談的下一部分將會在(2003年)98號,星期一貼出來。如果你想收到Artima.com上新文章每週簡報的電子郵件,請訂閱Artima Newsletter

反饋

對本文所描述的設計原則有自己的觀點麼?那麼請到News&Ideas論壇討論這篇文章The Trouble with Checked Exceptions

資源

深入C#:微軟主架構師Anders Hejlsberg訪談:

http://windows.oreilly.com/news/hejlsberg_0800.html

A Comparative Overview of C#:
http://genamics.com/developer/csharp_comparative.htm

Microsoft Visual C#:
http://msdn.microsoft.com/vcsharp/

Anders Hejlsberg不是Artima的採訪對象中第一個提到品味的。Jim Waldo在他的訪談中針對構建一個由有品味的程序員組成的團隊給出了幾乎同樣的評述:

http://www.artima.com/intv/waldo10.html

Ken Arnold’s的訪談有一整部分都是關於設計品味的——品味和美學(Taste and Aesthetics):
http://www.artima.com/intv/taste.html

<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章