|
|
oop: object oriented programming,面嚮對象的程序設計。所謂“對象”就是一個或一組數據以及處理這些數據的方法和過程的集合。面嚮對象的程序設計完全不同於傳統的面嚮過程程序設計,它大大地降低了軟件開發的難度,使編程就像搭積木一樣簡單,是當今電腦編程的一股勢不可擋的潮流。
面嚮對象編程(object oriented programming,oop,面嚮對象程序設計)是一種計算機編程架構。oop 的一條基本原則是計算機程序是由單個能夠起到子程序作用的單元或對象組合而成。oop 達到了軟件工程的三個主要目標:重用性、靈活性和擴展性。為了實現整體運算,每個對象都能夠接收信息、處理數據和嚮其它對象發送信息。oop 主要有以下的概念和組件:
組件 - 數據和功能一起在運行着的計算機程序中形成的單元,組件在 oop 計算機程序中是模塊和結構化的基礎。
抽象性 - 程序有能力忽略正在處理中信息的某些方面,即對信息主要方面關註的能力。
封裝 - 也叫做信息封裝:確保組件不會以不可預期的方式改變其它組件的內部狀態;衹有在那些提供了內部狀態改變方法的組件中,纔可以訪問其內部狀態。每類組件都提供了一個與其它組件聯繫的接口,並規定了其它組件進行調用的方法。
多態性 - 組件的引用和類集會涉及到其它許多不同類型的組件,而且引用組件所産生的結果得依據實際調用的類型。
繼承性 - 允許在現存的組件基礎上創建子類組件,這統一並增強了多態性和封裝性。典型地來說就是用類來對組件進行分組,而且還可以定義新類為現存的類的擴展,這樣就可以將類組織成樹形或網狀結構,這體現了動作的通用性。
由於抽象性、封裝性、重用性以及便於使用等方面的原因,以組件為基礎的編程在腳本語言中已經變得特別流行。python 和 ruby 是最近纔出現的語言,在開發時完全采用了 oop 的思想,而流行的 perl 腳本語言從版本5開始也慢慢地加入了新的面嚮對象的功能組件。用組件代替“現實”上的實體成為 javascript(ecmascript) 得以流行的原因,有論證表明對組件進行適當的組合就可以在英特網上代替 html 和 xml 的文檔對象模型(dom)。
一、oop的基本思想
oop的許多原始思想都來之於simula語言,並在smalltalk語言的完善和標準化過程中得到更多的擴展和對以前的思想的重新註解。可以說oo思想和oopl幾乎是同步發展相互促進的。與函數式程序設計(functional-programming)和邏輯式程序設計(logic-programming)所代表的接近於機器的實際計算模型所不同的是,oop幾乎沒有引入精確的數學描敘,而是傾嚮於建立一個對象模型,它能夠近似的反映應用領域內的實體之間的關係,其本質是更接近於一種人類認知事物所采用的哲學觀的計算模型。由此,導致了一個自然的話題,那就是oop到底是什麽?[d&t 1988][b.s 1991] .。在oop中,對象作為計算主體,擁有自己的名稱,狀態以及接受外界消息的接口。在對象模型中,産生新對象,舊對象銷毀,發送消息,響應消息就構成oop計算模型的根本。
對象的産生有兩種基本方式。一種是以原型(prototype)對象為基礎産生新的對象。一種是以類(class)為基礎産生新對象。原型的概念已經在認知心理學中被用來解釋概念學習的遞增特性,原型模型本身就是企圖通過提供一個有代表性的對象為基礎來産生各種新的對象,並由此繼續産生更符合實際應用的對象。而原型-委托也是oop中的對象抽象,代碼共享機製中的一種。一個類提供了一個或者多個對象的通用性描敘。從形式化的觀點看,類與類型有關,因此一個類相當於是從該類中産生的實例的集合。而這樣的觀點也會帶來一些矛盾,比較典型的就是在繼承體係下,子集(子類)對象和父集(父類)對象之間的行為相融性可能很難達到,這也就是oop中常被引用的---子類型(subtype)不等於子類(subclass)[budd 2002]。而在一種所有皆對象的世界觀背景下,在類模型基礎上還誕生出了一種擁有元類(metaclass)的新對象模型。即類本身也是一種其他類的對象。以上三種根本不同的觀點各自定義了三種基於類(class-based),基於原型(prototype-based)和基於元類(metaclass-based)的對象模型。而這三種對象模型也就導致了許多不同的程序設計語言(如果我們暫時把靜態與動態的差別放在一邊)。是的,我們經常接觸的c++,java都是使用基於類的對象模型,但除此之外還有很多我們所沒有接觸的oopl采用了完全不一樣的對象模型,他們是在用另外一種觀點詮釋oop的內涵。
什麽是oop的基本思想呢?把組件的實現和接口分開,並且讓組件具有多態性。不過,兩者還是有根本的不同。oop強調在程序構造中語言要素的語法。你必須得繼承,使用類,使用對象,對象傳遞消息。gp不關心你繼承或是不繼承,它的開端是分析産品的分類,有些什麽種類,他們的行為如何。就是說,兩件東西相等意味着什麽?怎樣正確地定義相等操作?不單單是相等操作那麽簡單,你往深處分析就會發現“相等”這個一般觀念意味着兩個對象部分,或者至少基本部分是相等的,據此我們就可以有一個通用的相等操作。再說對象的種類。假設存在一個順序序列和一組對於順序序列的操作。那麽這些操作的語義是什麽?從復雜度權衡的角度看,我們應該嚮用戶提供什麽樣的順序序列?該種序列上存在那些操作?那種排序是我們需要的?衹有對這些組件的概念型分類搞清楚了,我們才能提到實現的問題:使用模板、繼承還是宏?使用什麽語言和技術?gp的基本觀點是把抽象的軟件組件和它們的行為用標準的分類學分類,出發點就是要建造真實的、高效的和不取决於語言的算法和數據結構。當然最終的載體還是語言,沒有語言沒法編程。stl使用c++,你也可以用ada來實現,用其他的語言來實現也行,結果會有所不同,但基本的東西是一樣的。到處都要用到二分查找和排序,而這就是人們正在做的。對於容器的語義,不同的語言會帶來輕微的不同。但是基本的區別很清楚是gp所依存的語義,以及語義分解。例如,我們决定需要一個組件swap,然後指出這個組件在不同的語言中如果工作。顯然重點是語義以及語義分類。而oop所強調的(我認為是過分強調的)是清楚的定義類之間的層次關係。oop告訴了你如何建立層次關係,卻沒有告訴你這些關係的實質。
(這段不太好理解,有一些術語可能要過一段時間纔會有合適的中文翻譯——譯者)
面嚮對象的編程方法oop是九十年代纔流行的一種軟件編程方法。它強調對象的“抽象”、“封裝”、“繼承”、“多態”。我們講程序設計是由“數據結構”+“算法”組成的。從宏觀的角度講,oop下的對象是以編程為中心的,是面嚮程序的對象。我們今天要講的ood是面嚮信息的對象,是以用戶信息為中心的。
二、oop技術的歷史
面嚮對象技術最初是從面嚮對象的程序設計開始的,它的出現以60年代simula語言為標志。80年代中後期,面嚮對象程序設計逐漸成熟,被計算機界理解和接受,人們又開始進一步考慮面嚮對象的開發問題。這就是九十年代以microsoft visual係列oop軟件的流行的背景。
傳統的結構化分析與設計開發方法是一個綫性過程,因此,傳統的結構化分析與設計方法要求現實係統的業務管理規範,處理數據齊全,用戶能全面完整地其業務需求。
傳統的軟件結構和設計方法難以適應軟件生産自動化的要求,因為它以過程為中心進行功能組合,軟件的擴充和復用能力很差。
對象是對現實世界實體的模擬,因面能更容易地理解需求,即使用戶和分析者之間具有不同的教育背景和工作特點,也可很好地溝通。
區別面嚮對象的開發和傳統過程的開發的要素有:對象識別和抽象、封裝、多態性和繼承。
對象(object)是一個現實實體的抽象,由現實實體的過程或信息牲來定義。一個對象可被認為是一個把數據(屬性)和程序(方法)封裝在一起的實體,這個程序産生該對象的動作或對它接受到的外界信號的反應。這些對象操作有時稱為方法。對象是個動態的概念,其中的屬性反映了對象當前的狀態。
類(class)用來描述具有相同的屬性和方法的對象的集合。它定義了該集合中每個對象所共有的屬性和方法。對象是類的實例。
由上分析不難看出,儘管oop技術更看中用戶的對象模型,但其目的都是以編程為目的的,而不是以用戶的信息為中心的,總想把用戶的信息納入到某個用戶不感興趣的“程序對象”中。
三、oop 的優缺點
· oop 的優點:使人們的編程與實際的世界更加接近,所有的對象被賦予屬性和方法,結果編程就更加富有人性化。
· oop 的也有缺點,就 c++ 而言,由於面嚮更高的邏輯抽象層,使得 c++ 在實現的時候,不得不做出性能上面的犧牲,有時候甚至是致命的 ( 所有對象的屬性都經過內置多重指針的間接引用是其性能損失的主要原因之一;不過,筆者的局限性在於未使用過 vc++ 外的面嚮對象語言,所以不是十分肯定,哈哈,有人笑出來了… )。
在計算機速度飛速發展的今天,你可能會說,一丁點的性能犧牲沒什麽大不了。是的,從面嚮對象的角度,使的編程的結構更加清晰完整,數據更加獨立和易於管理,性能的犧牲可以帶來這麽多的好處,沒有理由不做穩賺的生意吧?
不過,在某些對速度要求極高特殊場合,例如你做的是電信的交換係統,每秒鐘有超過百萬的人同時進行電話交換,如果,每一個數據交換過程都是一個對象,那麽總的性能損失將是天文數字!!
或者這個例子不夠貼身,再舉個例子吧。假如你受聘於一個遊戲設計公司,老闆希望做出來的遊戲可以更多的兼顧到更多的電腦使用者,遊戲每秒鐘的運行的幀可以更多,子彈和爆炸物可以更多、更華麗。那麽,你會發現使用 c++ 會使你的程序變得笨拙,無法滿足你的需求,除非你非得要你的遊戲運行於奔騰四的機器上 ( 如果不是,而你又堅持用 c++ 的對象編程,那麽請減少主角的槍的威力吧 )。
如果你是冥頑不寧的人,你說不相信 oop 會有性能上的損失,那麽,我記得曾看到在 csdn 上關於 vb 和 vc 執行效率的討論的文章,講述的就是使用了 mfc 以後,執行效率甚至低於 vb 開發出來的東西。請各位驗證一下:如果使用的是純粹的 c 語言語法的話,那麽一定會比在 vb 編出來的東西要快很多 ( gettickcount 函數可以查閱 msdn ,如果想更加精確一些,可以使用 queryperformancecounter 函數 )。
四、oop的未來(撰文/bjarne stroustrup & tim lindholm 編譯/孟岩)
在未來三年,程序員編寫代碼的方式會發生那些變化?
stroustrup: 在c++中,假如沒有合適的庫在背後支撐,完成任何重要的工作都可能是很復雜的。而一旦有了合適的庫,任何東西都可以被我們操控於股掌之間。因此,構造和使用程序庫的重要性與日俱增。這也暗示我們,泛型程序設計(generic programming)將會越來越多地被運用。衹有通過gp,我們才能確保庫的通用性和高效率。我還預期在分佈式計算和“組件(components)”應用領域會出現喜人的增長。就大部分程序員而言,通過使用方便適用的程序庫,這些開發工作會變得簡單明了。
現在有一個趨勢,編譯器廠商試圖把其特有的“對象模型”和圖形界面(gui)細節推銷給用戶。比如微軟的com和inprise的類屬性“properties”。對於用戶來說,這既不必要,也不情願。我所希望看到的程序庫,應該是用標準c++打造,界面靈活,值得信賴的程序庫。通常,這些界面應該是平臺無關的。c++的表達能力極強,即使不使用大量的宏,也應該足以達成這一要求。就算有些地方無法百分之百的遵守這一原則,也應該將對於平臺和廠傢的依賴性限製起來。這個目標的完成情況,可以反映軟件工具産業對於應用程序開發行業的關註程度。我懷疑目前對於那些獨立的、跨平臺廠商來說,並不存在相應的市場。如果能夠建立這樣的市場,也許能夠促進廠商們為客戶做出“真正有用的”産品。
lindholm: 對於編寫代碼的開發者來說,主要的驅動力量仍將是兩個:網絡和分佈式——也就是設計和開發非單機軟件的需求。大部分的應用程序將不會是孤零零地運行在單一設備上,而是運用了類似ejb和jsp之類技術的,平臺無關的分佈式程序。程序員們將不得不面對分佈式計算的重重險阻。這將對許多程序員所依賴的設計模式、技術和直覺構成嚴峻的挑戰。這是選擇編程語言之前必須認識到的,儘管不同語言的設計特性可能促進或者阻礙這一轉化。
在網絡應用的增長中,一個很重要的部分是小型移動設備和特殊internet設備的爆炸性增長。這些設備各有各的操作係統,或者衹在某種特定的設備領域內有共同的操作係統。我們現在還可以一一列舉出這些設備——家庭接入設備、蜂窩電話、電子報紙、pda、自動網絡設備等等。但是這些設備領域的數量和深入程度將會很快變得難以估量。我們都知道這個市場大得驚人,pc的興起與之相比不過小菜一碟。因此在這些設備的應用程序市場上,競爭將會相當殘酷。獲勝的重要手段之一,就是盡快進入市場。開發人員需要優秀的工具,迅速高效地撰寫和調試他們的軟件。平臺無關性也是製勝秘訣之一,它使得程序員能夠開發出支持多種設備平臺的軟件。
我預期的另一個變化是,我們對於代碼(java)和數據(xml)協同型應用程序的開發能力將會不斷提高。這種協同是開發強大應用程序的核心目標之一。我們從xml的迅速流行和ebxml規範的進展中,已經看到了這個趨勢。ebxml是一個針對電子商務和國際貿易的,基於xml的開放式基礎構架,由聯合國貿易促進和電子商務中心(un/cefact)與結構性信息標準推進組織(oasis)共同開發。
我們能否期望出現一個真正的面嚮組件(component-oriented)的語言?它的創造者會是誰呢?
stroustrup: 我懷疑,這個領域中之所以缺乏成果,正是因為人們——主要是那些非程序員們——對“組件”這個意義含糊的字眼寄予了太多的期望。這些人士夢想,有朝一日,組件會以某種方式把程序員趕出歷史舞臺。以後那些稱職的“設計員”衹需利用預先調整好的組件,把鼠標拖一拖放一放,就把係統組合出來。對於軟件工具廠商來說,這種想法還有另一層意義,他們認為,到時候衹有他們纔保留有必要的技術,有能力編寫這樣的組件。
這種想法有一個最基本的謬誤:這種組件很難獲得廣泛歡迎。一個單獨的組件或框架(framework),如果能夠滿足一個應用程序或者一個産業領域對所提出的大部分要求的話,對於其製造者來說就是划算的産品,而且技術上也不是很睏難。可是該産業內的幾個競爭者很快就會發現,如果所有人都采用這些組件,那麽彼此之間的産品就會變得天下大同,沒什麽區別,他們將淪為簡單的辦事員,主要利潤都將鑽進那些組件/框架供應商的腰包裏!
小“組件”很有用,不過産生不了預期的杠桿效應。中型的、更通用的組件非常有用,但是構造時需要非同尋常的彈性。
在c++中,我們綜合運用不同共享形式的類體係(class hierarchies),以及使用templates精心打造的接口,在這方面取得了一定的進展。我期待在這個領域取得一些有趣和有用的成果,不過我認為這種成果很可能是一種新的c++程序設計風格,而不是一種新的語言。
lindholm: 編寫面嚮組件的應用程序,好像更多的是個投資、設計和程序員管理方面的問題,而不是一個編程語言問題。當然某些語言在這方面具有先天優勢,不過如果說有什麽魔術般的新語言能夠大大簡化組件的編寫難度,那純粹是一種誤導。
微軟已經將全部賭註押在[font id=mark style="color: #ee6600; background-color: yellow"]c#[/font]上,其他語言何去何從?
stroustrup: c++在下一個十年裏仍然將是一種主流語言。面對新的挑戰,它會奮起應對。一個創造了那麽多出色係統的語言,絶不會“坐視落花流水春去也”。
我希望微軟認識到,它在c++(我指的是iso標準c++)上有着巨大的利益,c++是它與it世界內其他人之間的一座橋梁,是構造大型係統和嵌入式係統的有效工具,也是滿足高性能需求的利器。其他語言,似乎更註重那些四平八穩的商用程序。
競爭
[font id=mark style="color: #ee6600; background-color: yellow"]c#[/font]會不會獲得廣泛的接受,並且擠掉其他的語言?
lindholm: 通常,一種語言既不會從別的語言那裏獲利,也不會被擠掉。那些堅定的fortran程序員不還用着fortran嗎?對於個人來說,語言的選擇當然因時而異,但就整體而言,語言的種類衹會遞增,也就是說,它們之間的關係是“有你有我”而不是“有你沒我”。
對於一個新語言的接受程度,往往取决於其能力所及。java技術被迅速接受,原因是多方面的,internet和world wide web接口,在其他技術面前的挫折感,對於java技術發展方向的全面影響能力,都是原因。另一個重要的原因是java獨立於廠商,這意味着在兼容産品面前可以從容選擇。
[font id=mark style="color: #ee6600; background-color: yellow"]c#[/font]是否會獲得廣泛接受?視情況而定。總的來說,那些對於平臺無關性和廠商無關性漠不關心的程序員,可能會喜歡c#。那些跟微軟平臺捆在一起人當然可能想要尋找vb 和vc的一個出色的替代品。但是對於程序跨平臺執行能力特別關註的程序員,將會堅守java之類的語言。這種能力對於多重訪問設備(multiple access devices)和分佈式計算模型至關重要,而java語言提供了一個標準的、獨立於廠商運行時環境。
stroustrup: [font id=mark style="color: #ee6600; background-color: yellow"]c#[/font]的流行程度幾乎完全取决於微軟投入的資金多少。看上去[font id=mark style="color: #ee6600; background-color: yellow"]c#[/font]的興起肯定會犧牲掉其他一些語言的利益,但是事實上未必如此。java的蓬勃發展並沒有給c++帶來衰敗。c++的應用仍然在穩定增長(當然,已經不是爆炸性的增長了)。也許其他的語言也還能獲得自己的一席之地。
不過,我實在看不出有什麽必要再發明一種新的專有語言。特別是微軟,既生vb,何需c#?
不同oop語言各有什麽優勢和劣勢?
stroustrup: c++的優點自始至終都是這麽幾條:靈活、高效,而且並非專有語言。現在iso c++標準的出現,鞏固了最後一點。
我認為c++的高效是它最基本的優點。這種高效來自於其特有的數據和計算模型,較之java和c#,這種模型更加貼近機器。不過,哪些程序纔真正地渴望這麽高的效率?這是個問題。我認為這類程序非常多。人們對於計算機的期望,永遠都超越硬件科技的發展速度。很顯然,java和[font id=mark style="color: #ee6600; background-color: yellow"]c#[/font]的設計者的想法不同,他們認為,在很多地方效率問題無關緊要。
c++主要的缺點,歸罪於糟糕的教育(是那些始終認為c++是個純粹面嚮對象語言的人,和那些把c++當成c語言變體的人導致了這種情況),歸罪於不同平臺上的不一致性,歸罪於不完整、不標準的編譯器實現,歸罪於平臺無關的係統級程序庫的缺少。
這些問題歸於一點,就是缺乏一個卓越的廠商,能夠滿足整個c++社區的需求,勇於投入大量的資金開發必要的程序庫。
lindholm: java技術的成功,是因為它在合適的時間,出現在合適的地點,而且合理地選擇了語言和計算平臺的支持目標。java並不是在所有場合都優於其他oop語言,但是對於出現的新問題能夠解决得很出色。它面嚮internet計算環境,避免了c++中晦澀的結構,成功翻越了繼承機製的惱人問題。垃圾收集機製顯著地提高了生産率,降低了復雜度。在網絡背景下使用虛擬機,以及有關安全性和動態加載的一係列設計選擇,迎合了正在出現的需求和願望。這些特性使java不僅成為現有程序員的新武器,而且也為新的程序員創造了繁榮的市場空間。
此外,java擁有一個標準化的、二進製形式的類庫,提供了必要的(當然並非充分的)平臺與廠商無關性。平臺與廠商無關性要求一項技術必須有清晰的規範,摒棄那些阻礙二進製標準實施的特性。c++雖然有一個iso標準,但其實甚至對於相同係統與相同指令體係的各個平臺,也提不出一個實用的、各版本兼容的二進製標準。
歷史上很多使用虛擬機的語言飽受責難,是因為其不夠出色的性能問題,而這要歸過於緩慢的解釋器和糟糕的垃圾收集器。java的早期實現也因為同樣的問題受到嚴厲的批評。但是自那時起,業界嚮新的虛擬機實現技術投入了大量資金,取得了顯著的效果,如今在大部分場合,java的性能跟常規的靜態編譯語言相比毫不遜色。這使得程序員在獲得平臺和廠商無關性的同時,也不必付出性能上的代價。
c++並沒有強製使用面嚮對象方法,因此為了編寫出色的面嚮對象代碼,就要求程序員們有相當強的紀律性。很多公司就是因為這個原因放棄了c++。作為語言,java的一個突出的優點就是強製面嚮對象方法,不允許非面嚮對象的結構。
[font id=mark style="color: #ee6600; background-color: yellow"]c#[/font]介於c++和java之間,腳踏兩衹船,因此既不夠安全,又失之復雜。
對於公司來說,采用新的語言要付出巨大代價。雇不到好的程序員(沒人熟悉這種新語言),培訓費用高得驚人,學習過程中生産率和産品質量下降,多年的經驗隨風消逝,等等。一種語言如何剋服這些障礙?
lindholm: 說得很對,采用新東西確實常常開銷巨大。不過問題是:這個新東西是否能夠節省更多的開支,或者提供巨大的改進,獲取合理的回報?很多公司發現,轉嚮java技術不論在開發的後端(盡快進入市場、快速迭代開發、維護簡單性)還是前端(跨平臺發佈,適用範圍從低端設備到高端服務器的技術,安全性),都能節省大筆的開銷。
對於新事物的接納,常常是在痛楚的壓力之下。很大程度上,這正是java所經歷的。java的産生,是對當時很多係統的缺陷所做出的反應。java技術通過下面的手段減輕了開發者的痛楚:1) 顧及了網絡計算方面的需求,是應運而生。2) 在技術能力的抉擇上,保持良好的品位,顧及了大衆的心理。3) 采用適度強製性策略推行設計决定。此外,java技術已經成為大學教學中的主流,這同樣保證了java開發者隊伍的不斷壯大。
但是最重要的一點是,再沒有另一種程序設計技術,能夠像java那樣允許程序員開發基於internet的不同平臺之上的應用程序。java平臺在這方面的傑出表現,已經被大量的實例證明。java已經成為internet上的缺省應用程序平臺,java apis也成為internet應用程序開發的天然平臺。
stroustrup: 微軟和sun把大筆的金錢扔在java、vb和[font id=mark style="color: #ee6600; background-color: yellow"]c#[/font]中,並不是因為他良心發現,也不是因為他們真的相信這些語言能夠帶給程序員更美好的生活,而是利益使然。
有一個說法,認為軟件工具廠商如果能夠把應用程序開發者的專業技術任務負擔起來,將獲取巨大的經濟利益。我對其背後的經濟分析頗為懷疑,我認為這很難成為現實,特別是當應用程序開發者使用開放的、標準化的工具時,他們可以有多種選擇,從而使上面的想法更加不可能。
多年以前,c++就已經具有泛型能力(也就是templates和stl),有運算符重載,有枚舉類型?我們會不會在java的未來版本中看到這些特性?java是不是應該納入這些特性呢?
strousturp:從1988-89年起,c++就已經有了templates。但是我們花了不少時間來瞭解如何最好地運用這個工具,早期各廠傢對於template的支持在品質上也有很大的差異。有些編譯器廠商動作遲緩,至少有一個主要的編譯器廠商(好像是指微軟,微軟在visual c++4.0纔開始支持template,在此之前一直聲稱template是過於復雜而又沒什麽用的技術,時至今日,visual c++對於template的支持在主流編譯器中都屬於最差的一檔——譯者註)暗中鼓勵聲名狼藉的反template宣傳,直到他們自己終於學會了這項技術為止。直到今天,對於template的支持在品質上仍然有待改進。
你上面提到的那些特性,我認為java(還有c#)應該,也肯定會逐漸引入。那些對於程序員來說最有用的語言特性和概念,將會逐漸集中,成為各傢主流語言的必然之選。也就是說,我認為類似析構函數和模板特殊化之類的機製,遠遠比枚舉等機製重要得多。
lindholm:java技術成功的原因之一,就是很清楚哪些不該做。我們得多問幾個為什麽:這項特性是不是必不可少?增加它會帶來哪些開銷?運算符重載是c++中一項極其強大的特性,但是它也大大增加了c++語言的復雜度,很多人都難以招架。java在各種可能的權衡之中,做出了明智的抉擇,找到了能力與需求之間的完美平衡點。
當然,java也會發展,而且最重要的是,現在是開發者們在推動發展。java增加泛型能力這件事,很好地展示了java是如何通過整個開發者社群的參與,在權衡中决定正確的平衡點。關於增加泛型類型(generic types)的“java規格申請”(java specification request, jsr)已經進入jcp(java community process)程序,而且已經開發了很長一段時間(參見 http://java.sun.com/aboutjava/communityprocess/之jsr-014)。現在,在jcp中,有超過80個jsrs正在討論中,這充分體現了整個體係對開發者的積極反饋和高度合作,這正是驅動java平臺不斷進化的動力。
發展 vs. 革新(evolution vs. revolution)
c++是一種發展型的語言,java和[font id=mark style="color: #ee6600; background-color: yellow"]c#[/font]似乎更像是革新型語言(它們是從頭設計的)?什麽時候,革新型的語言纔是必需的呢?
lindholm: java技術並非憑空出世,反而更像是發展型的。java所有的特性,在java平臺推出之前,都至少已經存在於另一種環境之中。java的貢獻在於,在衆多的特性和權衡中,做出了合理的選擇,使得産品既實用,又優雅。java技術對於程序員的態度是:撫養,但不溺愛。
stroustrup:從技術上講,我並不認為java和[font id=mark style="color: #ee6600; background-color: yellow"]c#[/font]是什麽“從頭設計的”革新型語言。倘若java是從技術原則出發,從頭設計,大概就不會模仿c/c++那種醜陋和病態的語法了(不必驚訝,stroustrup在很多場合表示過,c++采用c的語法形式,實在是迫於兼容性。他本人更偏愛simula的語法——譯者)。
我認為,衹有當程序員們面對的問題發生了根本的變化的時候,或者當我們發現了全新的、極其優越的程序設計技術,又完全不能為現存語言所支持的時候,我們纔需要全新的語言。問題是,我們恐怕永遠也碰不到那些“根本”、“全新”的情況。
我以為,自從oop問世以來,可稱為“根本”的新型程序設計技術,唯有泛型程序設計(generic programming)和生成式程序設計(generative programming)技術,這兩項技術主要是源於c++ templates技術的運用,也有一部分曾經被視為面嚮對象和函數式語言(functional languages)的次要成分,現在都變成正式、可用和可承受的技術了。我對於目前c++模板(template)程序設計的成果非常興奮。例如,像pooma, blitz++和mtl等程序庫,在很多地方改變了數值計算的方式。
java和[font id=mark style="color: #ee6600; background-color: yellow"]c#[/font]的一個“賣點”,就是它們的簡單性。現在java是不是快失去這個賣點了?
stroustrup:新語言總是宣稱自己如何如何簡單,對老語言的復雜性頗多非議。其實這種所謂的“簡單性”,簡單地說,就是不成熟性。語言的復雜性,是在解决現實世界中極為煩瑣和特殊的復雜問題的過程中逐漸增加的。一個語言衹要活的時間夠長,總會有某些地方逐漸復雜起來,或者是語言本身,或者是程序庫和工具。c++和java顯然都不例外,我看[font id=mark style="color: #ee6600; background-color: yellow"]c#[/font]也一樣。如果一種語言能夠度過自己的幼年時代,它會發現,自己無論是體積還是復雜性都大大增加了。
lindholm:java技術的的功能在增加,需要學習的東西也在增加。不過功能的增加並不一定帶來復雜性的增加。java技術的發展,並沒有使學習麯綫更加陡峭,衹是讓它繼續嚮右方延展了。
標準
標準化語言和開放型語言各自的優點和缺點何在?
lindholm:對於一個開放、不允許專有擴展、具有權威的強製性標準語言或者運行環境來說,不存在什麽缺點。允許專有擴展就意味着允許廠商下套子綁架客戶。特別重要的是,必須讓整個平臺,而不衹是其中一部分完全標準化,才能杜絶廠商們利用高層次的專有api下套子。客戶要求有選擇廠商的自由,他們既要有創造性,又需要兼容性。
stroustrup:對於一個語言,如c/c++來說,建立正式標準(如iso標準)最大的好處,在於可以防止某一個廠商操縱這種語言,把它當成自己的搖錢樹。多個廠商的競爭給用戶帶來的是較低的價位和較好的穩定性。
專有語言的好處,一是流行,二是便宜(不過等你被套牢了之後,情況就會起變化),三是對於商業性需求可以做出快速的反應。
標準化語言的特點之一是,它不能忽略特殊用戶的需求。比如我在at&t中所考慮的東西,其規模、可靠性和效率要求,跟那些普通廠商關註的大衆軟件相比,根本不可同日而語。那些公司很自然衹關註主要的需求。
然而,多數大機構和身處前沿的公司,都有着特殊的需求。c++的設計是開放、靈活和高效的,能夠滿足我所能想象的任何需求。跟其他的現代語言相比,c++的傢長式作風可謂少之又少,原因就在這。當然,不能贊賞這一點的人會詬病c++的“危險”。
擁有正式和開放標準的語言主要是為編程工具的使用者和客戶服務的,而擁有專屬“標準”的語言,主要是為廠商服務的。
相關詞條:aop |
|
oop的許多原始思想都來之於Simula語言,並在Smalltalk語言的完善和標準化過程中得到更多的擴展和對以前的思想的重新註解。可以說OO思想和oopL幾乎是同步發展相互促進的。與函數式程序設計(functional-programming)和邏輯式程序設計(logic-programming)所代表的接近於機器的實際計算模型所不同的是,oop幾乎沒有引入精確的數學描敘,而是傾嚮於建立一個對象模型,它能夠近似的反映應用領域內的實體之間的關係,其本質是更接近於一種人類認知事物所采用的哲學觀的計算模型。由此,導致了一個自然的話題,那就是oop到底是什麽?[D&T 1988][B.S 1991] .。在oop中,對象作為計算主體,擁有自己的名稱,狀態以及接受外界消息的接口。在對象模型中,産生新對象,舊對象銷毀,發送消息,響應消息就構成oop計算模型的根本。
對象的産生有兩種基本方式。一種是以原型(prototype)對象為基礎産生新的對象。一種是以類(class)為基礎産生新對象。原型的概念已經在認知心理學中被用來解釋概念學習的遞增特性,原型模型本身就是企圖通過提供一個有代表性的對象為基礎來産生各種新的對象,並由此繼續産生更符合實際應用的對象。而原型-委托也是oop中的對象抽象,代碼共享機製中的一種。一個類提供了一個或者多個對象的通用性描敘。從形式化的觀點看,類與類型有關,因此一個類相當於是從該類中産生的實例的集合。而這樣的觀點也會帶來一些矛盾,比較典型的就是在繼承體係下,子集(子類)對象和父集(父類)對象之間的行為相融性可能很難達到,這也就是oop中常被引用的---子類型(subtype)不等於子類(subclass)[Budd 2002]。而在一種所有皆對象的世界觀背景下,在類模型基礎上還誕生出了一種擁有元類(metaclass)的新對象模型。即類本身也是一種其他類的對象。以上三種根本不同的觀點各自定義了三種基於類(class-based),基於原型(prototype-based)和基於元類(metaclass-based)的對象模型。而這三種對象模型也就導致了許多不同的程序設計語言(如果我們暫時把靜態與動態的差別放在一邊)。是的,我們經常接觸的C++,Java都是使用基於類的對象模型,但除此之外還有很多我們所沒有接觸的oopL采用了完全不一樣的對象模型,他們是在用另外一種觀點詮釋oop的內涵。
什麽是oop的基本思想呢?把組件的實現和接口分開,並且讓組件具有多態性。不過,兩者還是有根本的不同。oop強調在程序構造中語言要素的語法。你必須得繼承,使用類,使用對象,對象傳遞消息。gp不關心你繼承或是不繼承,它的開端是分析産品的分類,有些什麽種類,他們的行為如何。就是說,兩件東西相等意味着什麽?怎樣正確地定義相等操作?不單單是相等操作那麽簡單,你往深處分析就會發現“相等”這個一般觀念意味着兩個對象部分,或者至少基本部分是相等的,據此我們就可以有一個通用的相等操作。再說對象的種類。假設存在一個順序序列和一組對於順序序列的操作。那麽這些操作的語義是什麽?從復雜度權衡的角度看,我們應該嚮用戶提供什麽樣的順序序列?該種序列上存在那些操作?那種排序是我們需要的?衹有對這些組件的概念型分類搞清楚了,我們才能提到實現的問題:使用模板、繼承還是宏?使用什麽語言和技術?gp的基本觀點是把抽象的軟件組件和它們的行為用標準的分類學分類,出發點就是要建造真實的、高效的和不取决於語言的算法和數據結構。當然最終的載體還是語言,沒有語言沒法編程。stl使用c++,你也可以用ada來實現,用其他的語言來實現也行,結果會有所不同,但基本的東西是一樣的。到處都要用到二分查找和排序,而這就是人們正在做的。對於容器的語義,不同的語言會帶來輕微的不同。但是基本的區別很清楚是gp所依存的語義,以及語義分解。例如,我們决定需要一個組件swap,然後指出這個組件在不同的語言中如果工作。顯然重點是語義以及語義分類。而oop所強調的(我認為是過分強調的)是清楚的定義類之間的層次關係。oop告訴了你如何建立層次關係,卻沒有告訴你這些關係的實質。
(這段不太好理解,有一些術語可能要過一段時間纔會有合適的中文翻譯——譯者)
面嚮對象的編程方法oop是九十年代纔流行的一種軟件編程方法。它強調對象的“抽象”、“封裝”、“繼承”、“多態”。我們講程序設計是由“數據結構”+“算法”組成的。從宏觀的角度講,oop下的對象是以編程為中心的,是面嚮程序的對象。我們今天要講的OOD是面嚮信息的對象,是以用戶信息為中心的。 |
|
面嚮對象技術最初是從面嚮對象的程序設計開始的,它的出現以60年代simula語言為標志。80年代中後期,面嚮對象程序設計逐漸成熟,被計算機界理解和接受,人們又開始進一步考慮面嚮對象的開發問題。這就是九十年代以Microsoft Visual係列oop軟件的流行的背景。
傳統的結構化分析與設計開發方法是一個綫性過程,因此,傳統的結構化分析與設計方法要求現實係統的業務管理規範,處理數據齊全,用戶能全面完整地其業務需求。
傳統的軟件結構和設計方法難以適應軟件生産自動化的要求,因為它以過程為中心進行功能組合,軟件的擴充和復用能力很差。
對象是對現實世界實體的模擬,因面能更容易地理解需求,即使用戶和分析者之間具有不同的教育背景和工作特點,也可很好地溝通。
區別面嚮對象的開發和傳統過程的開發的要素有:對象識別和抽象、封裝、多態性和繼承。
對象(Object)是一個現實實體的抽象,由現實實體的過程或信息牲來定義。一個對象可被認為是一個把數據(屬性)和程序(方法)封裝在一起的實體,這個程序産生該對象的動作或對它接受到的外界信號的反應。這些對象操作有時稱為方法。對象是個動態的概念,其中的屬性反映了對象當前的狀態。
類(Class)用來描述具有相同的屬性和方法的對象的集合。它定義了該集合中每個對象所共有的屬性和方法。對象是類的實例。
由上分析不難看出,儘管oop技術更看中用戶的對象模型,但其目的都是以編程為目的的,而不是以用戶的信息為中心的,總想把用戶的信息納入到某個用戶不感興趣的“程序對象”中。 |
|
· oop 的優點:使人們的編程與實際的世界更加接近,所有的對象被賦予屬性和方法,結果編程就更加富有人性化。
· oop 的也有缺點,就 C++ 而言,由於面嚮更高的邏輯抽象層,使得 C++ 在實現的時候,不得不做出性能上面的犧牲,有時候甚至是致命的 ( 所有對象的屬性都經過內置多重指針的間接引用是其性能損失的主要原因之一;不過,筆者的局限性在於未使用過 VC++ 外的面嚮對象語言,所以不是十分肯定,哈哈,有人笑出來了… )。
在計算機速度飛速發展的今天,你可能會說,一丁點的性能犧牲沒什麽大不了。是的,從面嚮對象的角度,使的編程的結構更加清晰完整,數據更加獨立和易於管理,性能的犧牲可以帶來這麽多的好處,沒有理由不做穩賺的生意吧?
不過,在某些對速度要求極高特殊場合,例如你做的是電信的交換係統,每秒鐘有超過百萬的人同時進行電話交換,如果,每一個數據交換過程都是一個對象,那麽總的性能損失將是天文數字!!
或者這個例子不夠貼身,再舉個例子吧。假如你受聘於一個遊戲設計公司,老闆希望做出來的遊戲可以更多的兼顧到更多的電腦使用者,遊戲每秒鐘的運行的幀可以更多,子彈和爆炸物可以更多、更華麗。那麽,你會發現使用 C++ 會使你的程序變得笨拙,無法滿足你的需求,除非你非得要你的遊戲運行於奔騰四的機器上 ( 如果不是,而你又堅持用 C++ 的對象編程,那麽請減少主角的槍的威力吧 )。
如果你是冥頑不寧的人,你說不相信 oop 會有性能上的損失,那麽,我記得曾看到在 CSDN 上關於 VB 和 VC 執行效率的討論的文章,講述的就是使用了 MFC 以後,執行效率甚至低於 VB 開發出來的東西。請各位驗證一下:如果使用的是純粹的 C 語言語法的話,那麽一定會比在 VB 編出來的東西要快很多 ( GetTickCount 函數可以查閱 MSDN ,如果想更加精確一些,可以使用 QueryPerformanceCounter 函數 )。 |
|
(撰文/Bjarne Stroustrup & Tim Lindholm 編譯/孟岩)
在未來三年,程序員編寫代碼的方式會發生那些變化?
Stroustrup: 在C++中,假如沒有合適的庫在背後支撐,完成任何重要的工作都可能是很復雜的。而一旦有了合適的庫,任何東西都可以被我們操控於股掌之間。因此,構造和使用程序庫的重要性與日俱增。這也暗示我們,泛型程序設計(generic programming)將會越來越多地被運用。衹有通過GP,我們才能確保庫的通用性和高效率。我還預期在分佈式計算和“組件(components)”應用領域會出現喜人的增長。就大部分程序員而言,通過使用方便適用的程序庫,這些開發工作會變得簡單明了。
現在有一個趨勢,編譯器廠商試圖把其特有的“對象模型”和圖形界面(GUI)細節推銷給用戶。比如微軟的COM和Inprise的類屬性“properties”。對於用戶來說,這既不必要,也不情願。我所希望看到的程序庫,應該是用標準C++打造,界面靈活,值得信賴的程序庫。通常,這些界面應該是平臺無關的。C++的表達能力極強,即使不使用大量的宏,也應該足以達成這一要求。就算有些地方無法百分之百的遵守這一原則,也應該將對於平臺和廠傢的依賴性限製起來。這個目標的完成情況,可以反映軟件工具産業對於應用程序開發行業的關註程度。我懷疑目前對於那些獨立的、跨平臺廠商來說,並不存在相應的市場。如果能夠建立這樣的市場,也許能夠促進廠商們為客戶做出“真正有用的”産品。
Lindholm: 對於編寫代碼的開發者來說,主要的驅動力量仍將是兩個:網絡和分佈式——也就是設計和開發非單機軟件的需求。大部分的應用程序將不會是孤零零地運行在單一設備上,而是運用了類似EJB和JSP之類技術的,平臺無關的分佈式程序。程序員們將不得不面對分佈式計算的重重險阻。這將對許多程序員所依賴的設計模式、技術和直覺構成嚴峻的挑戰。這是選擇編程語言之前必須認識到的,儘管不同語言的設計特性可能促進或者阻礙這一轉化。
在網絡應用的增長中,一個很重要的部分是小型移動設備和特殊Internet設備的爆炸性增長。這些設備各有各的操作係統,或者衹在某種特定的設備領域內有共同的操作係統。我們現在還可以一一列舉出這些設備——家庭接入設備、蜂窩電話、電子報紙、PDA、自動網絡設備等等。但是這些設備領域的數量和深入程度將會很快變得難以估量。我們都知道這個市場大得驚人,PC的興起與之相比不過小菜一碟。因此在這些設備的應用程序市場上,競爭將會相當殘酷。獲勝的重要手段之一,就是盡快進入市場。開發人員需要優秀的工具,迅速高效地撰寫和調試他們的軟件。平臺無關性也是製勝秘訣之一,它使得程序員能夠開發出支持多種設備平臺的軟件。
我預期的另一個變化是,我們對於代碼(Java)和數據(XML)協同型應用程序的開發能力將會不斷提高。這種協同是開發強大應用程序的核心目標之一。我們從XML的迅速流行和ebXML規範的進展中,已經看到了這個趨勢。ebXML是一個針對電子商務和國際貿易的,基於XML的開放式基礎構架,由聯合國貿易促進和電子商務中心(UN/CEFACT)與結構性信息標準推進組織(OASIS)共同開發。
我們能否期望出現一個真正的面嚮組件(component-oriented)的語言?它的創造者會是誰呢?
Stroustrup: 我懷疑,這個領域中之所以缺乏成果,正是因為人們——主要是那些非程序員們——對“組件”這個意義含糊的字眼寄予了太多的期望。這些人士夢想,有朝一日,組件會以某種方式把程序員趕出歷史舞臺。以後那些稱職的“設計員”衹需利用預先調整好的組件,把鼠標拖一拖放一放,就把係統組合出來。對於軟件工具廠商來說,這種想法還有另一層意義,他們認為,到時候衹有他們纔保留有必要的技術,有能力編寫這樣的組件。
這種想法有一個最基本的謬誤:這種組件很難獲得廣泛歡迎。一個單獨的組件或框架(framework),如果能夠滿足一個應用程序或者一個産業領域對所提出的大部分要求的話,對於其製造者來說就是划算的産品,而且技術上也不是很睏難。可是該産業內的幾個競爭者很快就會發現,如果所有人都采用這些組件,那麽彼此之間的産品就會變得天下大同,沒什麽區別,他們將淪為簡單的辦事員,主要利潤都將鑽進那些組件/框架供應商的腰包裏!
小“組件”很有用,不過産生不了預期的杠桿效應。中型的、更通用的組件非常有用,但是構造時需要非同尋常的彈性。
在C++中,我們綜合運用不同共享形式的類體係(class hierarchies),以及使用templates精心打造的接口,在這方面取得了一定的進展。我期待在這個領域取得一些有趣和有用的成果,不過我認為這種成果很可能是一種新的C++程序設計風格,而不是一種新的語言。
Lindholm: 編寫面嚮組件的應用程序,好像更多的是個投資、設計和程序員管理方面的問題,而不是一個編程語言問題。當然某些語言在這方面具有先天優勢,不過如果說有什麽魔術般的新語言能夠大大簡化組件的編寫難度,那純粹是一種誤導。
微軟已經將全部賭註押在C#上,其他語言何去何從?
Stroustrup: C++在下一個十年裏仍然將是一種主流語言。面對新的挑戰,它會奮起應對。一個創造了那麽多出色係統的語言,絶不會“坐視落花流水春去也”。
我希望微軟認識到,它在C++(我指的是ISO標準C++)上有着巨大的利益,C++是它與IT世界內其他人之間的一座橋梁,是構造大型係統和嵌入式係統的有效工具,也是滿足高性能需求的利器。其他語言,似乎更註重那些四平八穩的商用程序。
競爭
C#會不會獲得廣泛的接受,並且擠掉其他的語言?
Lindholm: 通常,一種語言既不會從別的語言那裏獲利,也不會被擠掉。那些堅定的Fortran程序員不還用着Fortran嗎?對於個人來說,語言的選擇當然因時而異,但就整體而言,語言的種類衹會遞增,也就是說,它們之間的關係是“有你有我”而不是“有你沒我”。
對於一個新語言的接受程度,往往取决於其能力所及。Java技術被迅速接受,原因是多方面的,Internet和World Wide Web接口,在其他技術面前的挫折感,對於Java技術發展方向的全面影響能力,都是原因。另一個重要的原因是Java獨立於廠商,這意味着在兼容産品面前可以從容選擇。
C#是否會獲得廣泛接受?視情況而定。總的來說,那些對於平臺無關性和廠商無關性漠不關心的程序員,可能會喜歡C#。那些跟微軟平臺捆在一起人當然可能想要尋找VB 和VC的一個出色的替代品。但是對於程序跨平臺執行能力特別關註的程序員,將會堅守Java之類的語言。這種能力對於多重訪問設備(multiple access devices)和分佈式計算模型至關重要,而Java語言提供了一個標準的、獨立於廠商運行時環境。
Stroustrup:C#的流行程度幾乎完全取决於微軟投入的資金多少。看上去C#的興起肯定會犧牲掉其他一些語言的利益,但是事實上未必如此。Java的蓬勃發展並沒有給C++帶來衰敗。C++的應用仍然在穩定增長(當然,已經不是爆炸性的增長了)。也許其他的語言也還能獲得自己的一席之地。
不過,我實在看不出有什麽必要再發明一種新的專有語言。特別是微軟,既生VB,何需C#? |
|
Stroustrup: C++的優點自始至終都是這麽幾條:靈活、高效,而且並非專有語言。現在ISO C++標準的出現,鞏固了最後一點。
我認為C++的高效是它最基本的優點。這種高效來自於其特有的數據和計算模型,較之Java和C#,這種模型更加貼近機器。不過,哪些程序纔真正地渴望這麽高的效率?這是個問題。我認為這類程序非常多。人們對於計算機的期望,永遠都超越硬件科技的發展速度。很顯然,Java和C#的設計者的想法不同,他們認為,在很多地方效率問題無關緊要。
C++主要的缺點,歸罪於糟糕的教育(是那些始終認為C++是個純粹面嚮對象語言的人,和那些把C++當成C語言變體的人導致了這種情況),歸罪於不同平臺上的不一致性,歸罪於不完整、不標準的編譯器實現,歸罪於平臺無關的係統級程序庫的缺少。
這些問題歸於一點,就是缺乏一個卓越的廠商,能夠滿足整個C++社區的需求,勇於投入大量的資金開發必要的程序庫。
Lindholm: Java技術的成功,是因為它在合適的時間,出現在合適的地點,而且合理地選擇了語言和計算平臺的支持目標。Java並不是在所有場合都優於其他oop語言,但是對於出現的新問題能夠解决得很出色。它面嚮Internet計算環境,避免了C++中晦澀的結構,成功翻越了繼承機製的惱人問題。垃圾收集機製顯著地提高了生産率,降低了復雜度。在網絡背景下使用虛擬機,以及有關安全性和動態加載的一係列設計選擇,迎合了正在出現的需求和願望。這些特性使Java不僅成為現有程序員的新武器,而且也為新的程序員創造了繁榮的市場空間。
此外,Java擁有一個標準化的、二進製形式的類庫,提供了必要的(當然並非充分的)平臺與廠商無關性。平臺與廠商無關性要求一項技術必須有清晰的規範,摒棄那些阻礙二進製標準實施的特性。C++雖然有一個ISO標準,但其實甚至對於相同係統與相同指令體係的各個平臺,也提不出一個實用的、各版本兼容的二進製標準。
歷史上很多使用虛擬機的語言飽受責難,是因為其不夠出色的性能問題,而這要歸過於緩慢的解釋器和糟糕的垃圾收集器。Java的早期實現也因為同樣的問題受到嚴厲的批評。但是自那時起,業界嚮新的虛擬機實現技術投入了大量資金,取得了顯著的效果,如今在大部分場合,Java的性能跟常規的靜態編譯語言相比毫不遜色。這使得程序員在獲得平臺和廠商無關性的同時,也不必付出性能上的代價。
C++並沒有強製使用面嚮對象方法,因此為了編寫出色的面嚮對象代碼,就要求程序員們有相當強的紀律性。很多公司就是因為這個原因放棄了C++。作為語言,Java的一個突出的優點就是強製面嚮對象方法,不允許非面嚮對象的結構。
C#介於C++和Java之間,腳踏兩衹船,因此既不夠安全,又失之復雜。
對於公司來說,采用新的語言要付出巨大代價。雇不到好的程序員(沒人熟悉這種新語言),培訓費用高得驚人,學習過程中生産率和産品質量下降,多年的經驗隨風消逝,等等。一種語言如何剋服這些障礙?
Lindholm: 說得很對,采用新東西確實常常開銷巨大。不過問題是:這個新東西是否能夠節省更多的開支,或者提供巨大的改進,獲取合理的回報?很多公司發現,轉嚮Java技術不論在開發的後端(盡快進入市場、快速迭代開發、維護簡單性)還是前端(跨平臺發佈,適用範圍從低端設備到高端服務器的技術,安全性),都能節省大筆的開銷。
對於新事物的接納,常常是在痛楚的壓力之下。很大程度上,這正是Java所經歷的。Java的産生,是對當時很多係統的缺陷所做出的反應。Java技術通過下面的手段減輕了開發者的痛楚:1) 顧及了網絡計算方面的需求,是應運而生。2) 在技術能力的抉擇上,保持良好的品位,顧及了大衆的心理。3) 采用適度強製性策略推行設計决定。此外,Java技術已經成為大學教學中的主流,這同樣保證了Java開發者隊伍的不斷壯大。
但是最重要的一點是,再沒有另一種程序設計技術,能夠像Java那樣允許程序員開發基於Internet的不同平臺之上的應用程序。Java平臺在這方面的傑出表現,已經被大量的實例證明。Java已經成為Internet上的缺省應用程序平臺,Java APIs也成為Internet應用程序開發的天然平臺。
Stroustrup: 微軟和Sun把大筆的金錢扔在Java、VB和C#中,並不是因為他良心發現,也不是因為他們真的相信這些語言能夠帶給程序員更美好的生活,而是利益使然。
有一個說法,認為軟件工具廠商如果能夠把應用程序開發者的專業技術任務負擔起來,將獲取巨大的經濟利益。我對其背後的經濟分析頗為懷疑,我認為這很難成為現實,特別是當應用程序開發者使用開放的、標準化的工具時,他們可以有多種選擇,從而使上面的想法更加不可能。
多年以前,C++就已經具有泛型能力(也就是templates和STL),有運算符重載,有枚舉類型?我們會不會在Java的未來版本中看到這些特性?Java是不是應該納入這些特性呢?
Strousturp:從1988-89年起,C++就已經有了templates。但是我們花了不少時間來瞭解如何最好地運用這個工具,早期各廠傢對於template的支持在品質上也有很大的差異。有些編譯器廠商動作遲緩,至少有一個主要的編譯器廠商(好像是指微軟,微軟在Visual C++4.0纔開始支持template,在此之前一直聲稱template是過於復雜而又沒什麽用的技術,時至今日,Visual C++對於template的支持在主流編譯器中都屬於最差的一檔——譯者註)暗中鼓勵聲名狼藉的反template宣傳,直到他們自己終於學會了這項技術為止。直到今天,對於template的支持在品質上仍然有待改進。
你上面提到的那些特性,我認為Java(還有C#)應該,也肯定會逐漸引入。那些對於程序員來說最有用的語言特性和概念,將會逐漸集中,成為各傢主流語言的必然之選。也就是說,我認為類似析構函數和模板特殊化之類的機製,遠遠比枚舉等機製重要得多。
Lindholm:Java技術成功的原因之一,就是很清楚哪些不該做。我們得多問幾個為什麽:這項特性是不是必不可少?增加它會帶來哪些開銷?運算符重載是C++中一項極其強大的特性,但是它也大大增加了C++語言的復雜度,很多人都難以招架。Java在各種可能的權衡之中,做出了明智的抉擇,找到了能力與需求之間的完美平衡點。
當然,Java也會發展,而且最重要的是,現在是開發者們在推動發展。Java增加泛型能力這件事,很好地展示了Java是如何通過整個開發者社群的參與,在權衡中决定正確的平衡點。關於增加泛型類型(generic types)的“Java規格申請”(Java Specification Request, JSR)已經進入JCP(Java Community Process)程序,而且已經開發了很長一段時間(參見 http://java.sun.com/aboutJava/communityprocess/之JSR-014)。現在,在JCP中,有超過80個JSRs正在討論中,這充分體現了整個體係對開發者的積極反饋和高度合作,這正是驅動Java平臺不斷進化的動力。 |
|
(Evolution vs. Revolution)
C++是一種發展型的語言,Java和C#似乎更像是革新型語言(它們是從頭設計的)?什麽時候,革新型的語言纔是必需的呢?
Lindholm: Java技術並非憑空出世,反而更像是發展型的。Java所有的特性,在Java平臺推出之前,都至少已經存在於另一種環境之中。Java的貢獻在於,在衆多的特性和權衡中,做出了合理的選擇,使得産品既實用,又優雅。Java技術對於程序員的態度是:撫養,但不溺愛。
Stroustrup:從技術上講,我並不認為Java和C#是什麽“從頭設計的”革新型語言。倘若Java是從技術原則出發,從頭設計,大概就不會模仿C/C++那種醜陋和病態的語法了(不必驚訝,Stroustrup在很多場合表示過,C++采用C的語法形式,實在是迫於兼容性。他本人更偏愛Simula的語法——譯者)。
我認為,衹有當程序員們面對的問題發生了根本的變化的時候,或者當我們發現了全新的、極其優越的程序設計技術,又完全不能為現存語言所支持的時候,我們纔需要全新的語言。問題是,我們恐怕永遠也碰不到那些“根本”、“全新”的情況。
我以為,自從oop問世以來,可稱為“根本”的新型程序設計技術,唯有泛型程序設計(generic programming)和生成式程序設計(generative programming)技術,這兩項技術主要是源於C++ templates技術的運用,也有一部分曾經被視為面嚮對象和函數式語言(functional languages)的次要成分,現在都變成正式、可用和可承受的技術了。我對於目前C++模板(template)程序設計的成果非常興奮。例如,像POOMA, Blitz++和MTL等程序庫,在很多地方改變了數值計算的方式。
C#的一個“賣點”,就是它們的簡單性。現在Java是不是快失去這個賣點了?
Stroustrup:新語言總是宣稱自己如何如何簡單,對老語言的復雜性頗多非議。其實這種所謂的“簡單性”,簡單地說,就是不成熟性。語言的復雜性,是在解决現實世界中極為煩瑣和特殊的復雜問題的過程中逐漸增加的。一個語言衹要活的時間夠長,總會有某些地方逐漸復雜起來,或者是語言本身,或者是程序庫和工具。C++和Java顯然都不例外,我看C#也一樣。如果一種語言能夠度過自己的幼年時代,它會發現,自己無論是體積還是復雜性都大大增加了。
Lindholm:Java技術的的功能在增加,需要學習的東西也在增加。不過功能的增加並不一定帶來復雜性的增加。Java技術的發展,並沒有使學習麯綫更加陡峭,衹是讓它繼續嚮右方延展了。
標準
標準化語言和開放型語言各自的優點和缺點何在?
Lindholm:對於一個開放、不允許專有擴展、具有權威的強製性標準語言或者運行環境來說,不存在什麽缺點。允許專有擴展就意味着允許廠商下套子綁架客戶。特別重要的是,必須讓整個平臺,而不衹是其中一部分完全標準化,才能杜絶廠商們利用高層次的專有API下套子。客戶要求有選擇廠商的自由,他們既要有創造性,又需要兼容性。
Stroustrup:對於一個語言,如C/C++來說,建立正式標準(如ISO標準)最大的好處,在於可以防止某一個廠商操縱這種語言,把它當成自己的搖錢樹。多個廠商的競爭給用戶帶來的是較低的價位和較好的穩定性。
專有語言的好處,一是流行,二是便宜(不過等你被套牢了之後,情況就會起變化),三是對於商業性需求可以做出快速的反應。
標準化語言的特點之一是,它不能忽略特殊用戶的需求。比如我在AT&T中所考慮的東西,其規模、可靠性和效率要求,跟那些普通廠商關註的大衆軟件相比,根本不可同日而語。那些公司很自然衹關註主要的需求。
然而,多數大機構和身處前沿的公司,都有着特殊的需求。C++的設計是開放、靈活和高效的,能夠滿足我所能想象的任何需求。跟其他的現代語言相比,C++的傢長式作風可謂少之又少,原因就在這。當然,不能贊賞這一點的人會詬病C++的“危險”。
擁有正式和開放標準的語言主要是為編程工具的使用者和客戶服務的,而擁有專屬“標準”的語言,主要是為廠商服務的。
相關詞條:AOP |
|
|