1. 程式人生 > >分清“語言/規範”以及“平臺/實現”,以及跨平臺.NET開發

分清“語言/規範”以及“平臺/實現”,以及跨平臺.NET開發

在許多年前,“語言”就等同於“平臺”,例如C,C++以及最早的Ruby和Python等等。但是隨著技術發展,出現了一些通用的平臺,例如.NET和Java,逐漸這些平臺上的語言也越來越多。再後來,某些語言在不同平臺上的實現也越來越多,事情也變得有些複雜。技術在發展,但是從目前社群的討論中,我發現許多朋友的觀念還沒有跟上。簡單地說,如今的觀念,一定要從“語言即平臺”切換成“語言及平臺”,當分清“語言”和“平臺”這兩個不同事物之後,許多問題才能討論地清楚。

例如我寫過一個太監繫列《Why Java Sucks and C# Rocks》,其中談的是C#和Java兩個“語言”而不是兩者的“平臺”。程式設計“語言”其實是一種“規範”,它涉及了程式設計師在使用這門語言時的文字表現形式(這裡暫不考慮其他形式的語言),而“平臺”則包括對這個規範的“實現”(廣義的“平臺”還包括整個生態環境等等)。C#和Java分別處在各自的平臺上,但許多語言其實是跨多種平臺的。例如Python,Ruby,Scala,Clojure,JavaScript等等,數不勝數。同樣,一個平臺上也會出現多種語言。而且事實上,由於.NET和Java這樣的平臺越來越成熟,語言的設計及實現者也都越來越傾向於讓語言執行在“某個平臺”上。這麼做可以儘可能地利用前人的成果,而不是什麼都要自己從頭做起。

其實基本的原則就是這麼簡單,但是真正在考慮問題的時候,可能就不是那麼容易了,我們必須時刻保持清晰地頭腦。

例如有個人說“C#比Java執行效率高(或低)”,這個說法是否正確?其實這種說法有很大問題。因為我們知道,在這裡C#和Java都是“語言”,它們的執行環境CLI及JVM一樣都是“規範”,但“執行效率”是一種表現,這和“實現”得如何有很大關係。例如,C#是執行在.NET平臺還是Mono上(它們都是CLI規範的具體實現),Java是執行在JRockit還是Hotspot(前者是Oracle的JVM商業實現,後者是Sun的開源實現——當然現在也是Oracle的),亦或是Android的Dalvik上?很顯然,不同實現之間的表現會有區別,不可一概而論,否則也不會出現JavaScript引擎的效率之爭了。同理,有些人使用Hotspot上的Java效能來說明Java在Android上執行時的表現,這也是不對的——要知道Google在和Oracle的Java專利官司中不斷強調Dalvik不是“Oracle那種Java”。作為結論,Java在Android上的表現的確不錯,但論證方式也必須正確才行。

當然,有時候“規範”也會影響到“實現”,例如一個動態分發的語言,其效能基本百分百不如在編譯期繫結的靜態語言。所以事情原本就是這麼複雜,做一個思路清晰的程式設計師並不是件容易的事情。順便一提,女人在這方面的頭腦一般都比較清楚,她們一般都知道騎白馬的不一定是王子,也有可能是唐僧。

對於俗稱“.NET程式設計師”的那一批人來說,分清“語言”和“平臺”更是一件十分重要的事情,因為C#語言可以說是目前“平臺”、“實現”最為廣泛的“語言”之一了。之前我為InfoQ寫過一篇文章,其中提到Mono的創始人Miguel de Icaza給出的目前C#語言可執行平臺的“不完全”列表,幾乎覆蓋了各種流行的作業系統及裝置等等,例如:

  • Windows
  • Mac OS
  • Linux / BSD / Solaris
  • Windows Phone,Android,iOS
  • XBox 360,Wii,PS3
  • ……

因此就拿C#這一種語言來說,“實現”也會各自略有不同,這便是所謂的“配置(Profile)”。目前至少已經有這麼多配置了:

  • .NET 4.0配置
  • Silverlight配置
  • Windows Phone 7配置
  • XBox360配置
  • Mono核心配置:與.NET配置相同,可以在Linux,MacOS X,Solaris,Windows和BSD裡使用。
  • .NET Micro Framework
  • Mono的iOS配置
  • Mono的Android配置
  • Mono的PS3配置
  • Mono的Wii配置
  • Moonlight配置(與Silverlight相容)
  • Moonlight擴充套件配置(Silverlight和完整的.NET 4 API)

“配置”之間的區別主要體現在執行環境的能力(例如iOS不支援執行時程式碼生成,因此支援AOT但不能JIT)以及類庫的覆蓋面上(例如XNA類庫只存在於Windows Phone及XBox 360等遊戲平臺),不過它們終究實現了一個核心規範,因此我們可以說在不同平臺上都可以“使用.NET進行開發”。

Mono實在是一個了不得的作品,它讓我知道了“跨平臺原來可以這麼做”。之前我也寫過有關跨平臺的問題,其中談到在“客戶端的跨平臺一般都很難得到最佳的體驗”,這個論點的最佳證明便是Java。但Mono走的卻是另一條跨平臺的道路,它在各平臺上實現了核心的執行引擎和類庫之外,解決“體驗”的方式便是在各個平臺上提供原生平臺的繫結。這樣無論是在Mac OS,iOS,Android上都可以得到原生應用的體驗。

我很奇怪為什麼有些搞.NET的人一邊說.NET的適用面太小,一邊卻忽視Mono的成果,在我看來這完全是“自作孽不可活”,我愈發覺得是否接受Mono是判斷一個.NET程式設計師是否優秀的重要準則。其實Mono實在很火,因為他為廣大.NET程式設計師擴充套件了工作領域,使用現有的知識來開發iOS等平臺的應用程式,還可以共享程式碼,何樂而不為?前不久蘋果釋出了Mac上的App Store,於是MonoMac也立即推出了面向AppStore的打包器Frank Krueger也開始著手移植它的作品iCircuit成果顯著。因此在我看來,這才是一個現代.NET程式設計師該有的工作臺:

對於MonoTouch這樣的新思路,帶有疑惑是正常的。我也知道還有許多聰明人可以找到各種反對的理由。不管怎樣,我現在這裡隨意列上幾條吧:

  • 有人說,用MonoTouch等.NET實現來做iOS開發“不正式”;我說,這個說法頗有“血統論”的意味,不過既然在Windows上用C++和Delphi都很正式,那麼為什麼在iOS上使用Objective-C才是正途?
  • 有人說,MonoTouch效能一定不如Objective-C好;我說,這是猜測,即使效能不如Objective-C,看看各種案例也知道這在實踐中並不是問題(事實上MonoTouch的前身便是Unity3D對Mono的使用,而iOS上實在有太多遊戲在使用Unity3D了)。
  • 有人說,MonoTouch或MonoDroid沒有大公司支援,不靠譜;我說,您之前不是經常鄙視類似“開源沒有微軟靠譜”或是“微軟開發人員只知道微軟技術”這種說法的嗎?
  • 有人說,用MonoTouch等於拋棄了CocoaTouch社群,出了問題都沒人問;我說,MonoTouch的問題基本就是CocoaTouch的問題,MonoTouch的UI層就是CocoaTouch,有問題直接去CocoaTouch社群或CocoaTouch程式設計師,程式碼直接對映,類庫直接使用。
  • 有人說,用MonoTouch的人不好招;我說,用C#、.NET的人比用Objective-C、Cocoa多太多了。給我一個熟練使用.NET和C#的人,三天上手,一週成為能夠開發出成品的iOS開發者。
  • 有人說,難道就是為了用.NET所以用MonoTouch?我說,用MonoTouch/MonoDroid的好處很多,例如我可以在iOS、Android、Windows Phone甚至更多平臺上共享UI以外的程式碼,並可以直接使用大量.NET上的類庫——這點實在太方便了。不要問我為什麼Android上不能使用Java類庫,我只知道開發Andorid的同事發現SOAP訪問類庫沒有,REST找不到好的,JSON支援也只有最原始的支援,於是痛苦萬分。

我還知道,這些說法依舊擋不住出現基於MonoDroid的DeltaEngine,這是個跨平臺的遊戲引擎,在Mono的支援下可以執行在Linux,MacOS X,iOS和Android上,在微軟.NET支援下可以執行在XBox 360,Windows Phone 7自然還有普通的Windows系統上。在CES 2011上NVidia演示了一個遊戲Soul Craft,它執行在LG Optimus 2X,這個遊戲正是使用了DeltaEngine。

對於我們來說,最大的限制其實還是眼界和思維,突破這一屏障也是我組織nBazaar技術沙龍的目的之一。本週六將會舉辦第三屆nBazaar技術交流會,具體資訊請訪問http://nbazaar.org/。如果您還沒有報名,也可以直接前來,也歡迎帶上感興趣的朋友或同事。根據以往的經驗,場地就像乳溝,擠擠總是有的……