Thursday, September 18, 2008

談程式語言的選用

談程式語言的選用


程式員間倘若談到了程式語言之間的比較話題,無論比較的是那個程式語言較好、或那個程式語言最重要、或者應該學什麼程式語言最有幫助,總是能引起無止盡的論戰而且難以止息。這樣的話題就跟日本車、歐洲車孰優孰劣一樣,每個程式語言總有其基本支持群眾,爭論時往往各執一詞,使得這樣的討論主題很難歸納出什麼結論。

每個程式語言背後皆有其設計的中心思想及哲學,而每個程式語言也都隱含著有其設定的一套表述方式。每個程式員都有自己偏好的程式語言,而這偏好之所以會建立,和學習程式語言的經驗、過程,以及個人特質有關。例如,有些程式員就是偏好直譯式語言,但是也有許多程式員對直譯式語言望之卻步。就和很多的個人愛好一樣,有時很難解釋為什麼你就是偏好某一個程式語言。

在早期雖也有許多程式語言的發明,但實際上用於一般軟體開發的實戰語言選擇並不多。而到了現今,各種程式語言百家爭鳴,一般程式員可以接觸到的程式語言數量遠勝以往,對於究竟該學習或該採用那一個程式語言,其中可以抉擇的空間又大了許多。

以我的觀點來看,程式語言間的比較,其實是不具太多的實質意義。倘若程式語言對你來說是一種純粹的嗜好,並不存在太多開發上的實務考量,那麼僅以欣賞或喜好的心情來看待一個程式語言,甚至做為其擁護者,那麼是否選用一個程式語言,就是一個完全由個人愛好來決定的事情。但是,倘若你是在開發的過程中要選擇一個程式語言,那麼需要考量的事情相較之下就會複雜許多。

事實上,每個語言都有它特有的性質,發明者在設計每個程式語言時多半也都設定了一定的目標範圍,以及想要解決的軟體開發問題。隨著程式員的實際應用以及語言本身的逐漸演化,每個語言都會被發掘出適合的應用領域。

沒有一個程式語言是打遍天下無敵手的,每個語言都有各自的優點和缺點。優點的另一面往往就是缺點所在,例如Java的垃圾收集機制,簡化了程式員配置、釋放記憶體的模式,大幅的降低了程式員因為犯下錯誤存取記憶體的問題而耗去的大量除錯時間。但是,也因為垃圾收集機制的關係,使得Java虛擬機器設計更形複雜,也影響到Java虛擬機器執行時期的效率。你所開發的應用程式,或許可以接受現今Java虛擬機器的運行效能(事實上,Java虛擬機器的運行效能應當足以開發大多數我們會接觸到的應用程式),而選擇使用Java來避免無形中的錯誤,藉以提昇開發時的生產力。但如果你所開發的程式極需執行效能,例如多媒體視訊或音訊的解碼器,便可能採用像C或C++之類的程式語言,甚至使用組合語言來撰寫,在這種應用情境下,開發的生產力不是關鍵,因為執行效能已經成了必要的門檻。所以,選擇開發時採用的程式語言,其實只是取與捨的判斷,優劣好壞不過都只是相對的特性,而沒有絕對的論斷方式。

程式語言也有流行的情況,你或許觀察到新問世的程式語言有時能引起一陣風潮,讓程式員們爭相追逐。但不可諱言的是,即使一個程式語言能引起短暫的流行,但每個程式語言都需要經過殘酷的考驗才得以生存下來。而歷時多年尚能存活至今的程式語言,無一不具備其賴以生存的重要特性。與其爭辯程式語言的好與壞,不如放開成見了解每個程式語言的特性,適合做什麼,以及不適合做什麼,才能客觀的於其中進行選擇。

優秀的程式員應當是程式語言中立的(programming language neutral),也就是說,你或許會專長、熟悉於若干個程式語言,但因為開發上的需要,你可以很容易學會、適應其他的程式語言。也就是說,當你從事開發時,並不會被特定的程式語言所限制住。最起碼,你必須熟悉多個程式語言並且能夠自在的運用。主流的程式語言思維模式不出幾類,例如程序式、物件導向式、函數式、或是混合模式等等,同一類的語言間即使語言語法或特性有所差異,但畢竟是源自於相同的血統,觸類旁通並不是件難事。例如C++、Java以及C#,皆為一脈相承,尤其是Java和C#,二者相互模仿,熟悉Java的程式員,必能在極短時間熟悉C#,甚至應該不經太多的訓練,便能輕易的讀懂C#的程式碼。能以多種程式語言編寫,已然成了優秀程式員的判斷標準之一。

當你具備了以多種語言編寫程式的能力,就能夠(也應該)依照需求而非喜好來選擇程式語言,你也不會固定只採用一種程式語言來撰寫所有的程式。這已經是一個多語言開發的時代了。當你開發某個服務和產品時,時常會需要動用到多個程式語言。或許你會利用Java來開發伺服器端,利用C#開發客戶端的GUI部份,但利用C++開發客戶端的核心程式庫。選擇採用一個程式語言,是因為它最適合應用在你要應用的地方,而不是因為你最喜愛它。

那麼應當如何選擇開發所用的程式語言呢?通常這是一整個開發團隊針對要開發的專案而做的決策,因此必須考慮到所有團隊成員的技能特性。程式語言的選擇不單是個人化的,更是團隊化的。主要都會依據專案本身的特性及目標來決定欲使用的程式語言。你首先可能會考慮到客戶選用的平台,或者產品所設定的平台,有些程式語言基本上只在某些平台上可用,例如.NET上的程式語言,實務上只能在Windows的作業系統上執行。

除了平台之外,你會考慮到執行效能,有些系統元件必須滿足執行時間或者服務規模的限制,對於這些元件必須選用效能表現足堪滿足的程式語言。開發的生產力也是很重要的考量因素。專案都有其執行的時間期限,面對時程緊迫的網站應用程式,你或許會考慮以Ruby程式語言搭配RoR應用程式框架的方式來做為程式語言的主軸,善用RoR的高生產力。在提供.NET的Windows平台上,選擇C#之類的程式語言來開發GUI,生產力多半能勝過VC++搭配MFC的方式。此外,開發程式的穩定度、支援的程式庫豐富與否、或者是否提供了你所需的程式庫,都是選用時必須考慮的條件。

在同一系統中混用一種以上程式語言的情況已經愈來愈常見,這使得我們更能輕易的善用每個語言的優點,規避掉持定語言的缺點。採用多語言開發時,還必須考慮所選用的程式語言是否能夠相互整合,整合的方式、介面是否滿足需求及限制條件。例如使用Java做為主要的開發語言,又想使用C語言撰寫需要高效能的模組時,就必須考慮使用JNI(Java Native Interface)做為二者界接的方式,但使用JNI又會失去平台的可攜性,決策者就必須於其中取捨。

當兩個備選的程式語言條件勢均力敵或是相差不遠時,應該要選擇自己所熟悉的。對程式語言的熟悉度能夠讓你避免許多因為陌生而造成的不必要陷阱,也可以避免掉許多無謂的時間浪費。

許多程式員會擔心某個語言是否會退流行,或者是擔心沒有趕上最新流行的程式語言會讓自己淘汰。我的看法是,與其擔心沒有跟上最新的流行,不如想想如何掌握不同程式語言的共通之處,也就是本文中所提到的,主流的程式語言思維模式其實不脫幾類,而且甚至以物件導向與程序式混合的程式語言為主。熟悉這種表達方式,要操作不同的程式語言,其實只是語法以及細節的獨特語言特性不同,跨多語言其實不構成太大的問題。關鍵往往不會是在語法,而是在你怎麼做抽象層次上的設計。

與其爭辯程式語言孰優孰劣,不如更自在、更恰到好處的運用多種程式語言於你的開發之中。優秀的程式員應當是程式語言中立、能同時以多種程式語言從事編寫的。

No comments: