冒號(hào)和他的學(xué)生們
——程序員提高班紀(jì)事
21.后臺(tái)腳本
操千曲而后曉聲,觀千劍而后識(shí)器 ——《文心雕龍•知音》
“剩下四種動(dòng)態(tài)語言,我們將之歸為后臺(tái)腳本語言。”冒號(hào)說著畫了張圖表——
用戶
|
前臺(tái)語言:Visual Basic,Delphi,JavaScript
|
平臺(tái)語言:Java,C#
|
后臺(tái)腳本語言:Perl,PHP,Python,Ruby
|
系統(tǒng)語言:C,C++,D
|
機(jī)器
|
引號(hào)聽得仔細(xì):“我記得您開始是把這些語言劃分為C族靜態(tài)語言、非C族靜態(tài)語言和動(dòng)態(tài)語言三類的。”
冒號(hào)解釋:“那是按語法來劃分的,偏重理論;現(xiàn)在是按應(yīng)用來劃分,偏重實(shí)踐。”
句號(hào)旋即聯(lián)想到:“這種分法貌似三層架構(gòu)——前臺(tái)語言對(duì)應(yīng)表現(xiàn)層;平臺(tái)語言和后臺(tái)腳本語言對(duì)應(yīng)業(yè)務(wù)邏輯層;系統(tǒng)語言對(duì)應(yīng)數(shù)據(jù)層。”
“的確有些神似,但千萬不可混淆。”冒號(hào)提醒道,“三層架構(gòu)(three-tier architecture)是模塊設(shè)計(jì)上的邏輯劃分;而這里是按語言應(yīng)用范圍進(jìn)行的物理劃分——與用戶交互的是前臺(tái)語言,與機(jī)器交互的是系統(tǒng)語言,介于其中的為前臺(tái)提供服務(wù)同時(shí)又需要底層系統(tǒng)服務(wù)的是后臺(tái)語言。”
逗號(hào)詢問:“后臺(tái)語言又細(xì)分成平臺(tái)語言與后臺(tái)腳本語言?”
“這是基于程序(program)與腳本(script)、靜態(tài)與動(dòng)態(tài)而分的。”冒號(hào)進(jìn)行說明,“其實(shí)Perl,PHP,Python和Ruby都有自己的虛擬機(jī)(Virtual Machine),從這種意義上說它們也可作為平臺(tái)語言。但在實(shí)際應(yīng)用中,它們沒有Java平臺(tái)和.NET平臺(tái)那種凝聚力和核心作用,通常作為輕量級(jí)的解決方案。”
問號(hào)想探個(gè)究竟:“這是由于它們都是動(dòng)態(tài)語言的緣故嗎?”
冒號(hào)回答:“理論上動(dòng)態(tài)語言同樣能承擔(dān)大型應(yīng)用,但實(shí)踐上它們多作為粘合語言或用于中小型應(yīng)用。用句時(shí)髦的話來形容,暫時(shí)還是主流的配角或非主流的主角。畢竟在效率、類型安全、可用資源、開發(fā)工具、技術(shù)支持等方面,它們與Java、C#相比尚有一定差距。另外它們同屬‘草根’語言,雖有開源社區(qū)的大力支持,在影響力上與后者未可同日而語。”
嘆號(hào)揣測(cè):“說不定在不久的將來,動(dòng)態(tài)語言也會(huì)成為主流的主角。”
“世易時(shí)移,殊難逆料。但有一點(diǎn)可以肯定,語言的發(fā)展趨勢(shì)一定是動(dòng)靜結(jié)合、剛?cè)岵?jì)。”冒號(hào)斷言,“一方面以Java和C#為代表的靜態(tài)語言中嫁接了動(dòng)態(tài)語言的枝條;另一方面以Java和.NET為代表的平臺(tái)與動(dòng)態(tài)語言的交壤地帶也在逐步擴(kuò)大。比如JRuby允許Ruby與Java之間互相調(diào)用,類似的還有Jython、IronRuby、IronPython等等。此外值得一提的是,動(dòng)態(tài)語言最活躍的舞臺(tái)當(dāng)數(shù)LAMP,L-A-M-P。”
引號(hào)接茬:“L是Linux,A是Apache,M是MySQL,P是PHP。”
冒號(hào)補(bǔ)充道:“P也可指Perl、Python,甚至Ruby。”
句號(hào)調(diào)侃:“可惜Ruby的‘R’比‘P’多了一根尾巴。”
“有人為了自圓其說,干脆讓P表示‘Programming language’,這下所有語言都囊括其中了。老外就喜歡玩這種首字母縮略(acronym)的文字游戲。”冒號(hào)語帶調(diào)笑,“前面我們?cè)峒埃W(wǎng)絡(luò)應(yīng)用是生長(zhǎng)動(dòng)態(tài)語言最肥沃的土壤,而LAMP就是這塊土壤上搭建的平臺(tái)。作為開源網(wǎng)絡(luò)平臺(tái),LAMP以其開放靈活、開發(fā)迅速、成本低廉等特色而與Java平臺(tái)和.NET平臺(tái)鼎足三分,尤其受中小企業(yè)的歡迎。LAMP中Linux是操作系統(tǒng),Apache是Web服務(wù)器,MySQL是數(shù)據(jù)庫系統(tǒng),而我們當(dāng)下最關(guān)心的是‘P族語言’:PHP、Perl、Python還有Ruby。”
問號(hào)建議:“作為動(dòng)態(tài)語言,它們的共性上節(jié)課已經(jīng)談了不少,能說說它們的個(gè)性嗎?”
“它們的個(gè)性極為鮮明:Perl凝練晦澀,Python優(yōu)雅明晰,Ruby精巧靈動(dòng),PHP簡(jiǎn)明單純。先看老大哥Perl,它博采眾家之長(zhǎng),綜合了C語言的結(jié)構(gòu)、sed的正則表達(dá)式、AWK的關(guān)聯(lián)數(shù)組(associative array)、Lisp的表(list)和Unix Shell的命令,此外還有借鑒了一種語言,你們知道是哪種嗎?”冒號(hào)忽然賣了個(gè)關(guān)子。
逗號(hào)猜想:“應(yīng)該是某種OOP語言吧。”
“Perl中確有不少C++的影子,但它的對(duì)象模型在5.0以后才引入,典型的半路出家,遠(yuǎn)不如前面的特征那么自然。與其說是一種自然而然的發(fā)展,不如說是在OOP潮流裹挾下的一種身不由己的迎合。真正深入骨髓的借鑒是自然語言。”冒號(hào)給出了答案,“Perl的發(fā)明者Wall是一名語言學(xué)家,他認(rèn)為程序語言應(yīng)該與自然語言一樣,簡(jiǎn)潔自然、易讀易寫、表達(dá)多樣、不拘一格。Perl還有不少的格言或哲學(xué),使得編程語言一改嚴(yán)謹(jǐn)刻板的面孔,散發(fā)出濃郁的人文氣息。”
嘆號(hào)幽了一默:“我見過Perl的代碼,人文氣息沒聞出來,但我懷疑有乙醚氣息——看一會(huì)就覺得暈暈乎乎的。”
眾人大笑。
“有人僅用一行Perl代碼就實(shí)現(xiàn)了RSA算法,你看了那還不得當(dāng)場(chǎng)暈倒啊?”冒號(hào)打趣道,“Perl的各種魔符好似一把把鋒利的剪刀,做起文本裁剪之類的工作來游刃有余。這是它最大的長(zhǎng)處,當(dāng)初Perl就是Wall用來做Unix系統(tǒng)管理的,以后在CGI上的廣泛應(yīng)用也得益于此。但它既精練又復(fù)雜,影響了可讀性、一致性、整潔性和可維護(hù)性。不熟悉該語言的固然如讀天書,熟悉語言而不熟悉問題的也頗費(fèi)思量。相比之下Python被認(rèn)為是Perl有力的挑戰(zhàn)者,不僅在于它天然的OO設(shè)計(jì),更重要的是它對(duì)程序員友好度大大超過Perl。Python也有一系列的被稱為禪(Zen)的哲學(xué),不少與Perl是針鋒相對(duì)的。比如:Perl認(rèn)為做一件事可以有多種方法,而Python認(rèn)為一件事應(yīng)該最好只有一種方法;Perl追求語言的表現(xiàn)力,Python追求簡(jiǎn)單優(yōu)雅;Perl喜歡隱性暗示,Python強(qiáng)調(diào)顯性明示;Perl強(qiáng)調(diào)緊湊,Python強(qiáng)調(diào)松散; Perl的語法和語義豐富,Python的語法和語義簡(jiǎn)單而類庫豐富。或許Python最讓人不習(xí)慣的是它對(duì)空白符敏感性。”
引號(hào)感到驚奇:“對(duì)空白符敏感?這個(gè)倒真怪異。”
冒號(hào)見慣不怪:“雖然有點(diǎn)違反習(xí)慣,但非常符合Python一貫的規(guī)范簡(jiǎn)潔的風(fēng)格——一方面從語法上保證了良好的編碼風(fēng)格;另一方面,每個(gè)代碼塊不再需要起始的大括號(hào)或begin/end之類的,減少了的代碼行數(shù)。此外許多人抱怨Python中的自引用self太多,殊不知這也是它倡導(dǎo)顯式表達(dá)的一種體現(xiàn)。”
嘆號(hào)好奇地問:“Ruby怎么樣?據(jù)說它將取代Java。”
“不要輕言‘取代’二字。”冒號(hào)規(guī)誡道,“Java沒有取代C++,也不會(huì)被Ruby取代,至多只是一種再分配。不過Ruby的確是門很可愛的語言,兼具Perl的表現(xiàn)力和Python的可讀性。Ruby背后最具特色的理念是:關(guān)注程序員使用語言時(shí)的感受超過語言本身的功能。通俗地說,兵器的稱手比鋒利更重要;文雅地說,應(yīng)給予程序員更多的人文關(guān)懷。就拿代碼塊(block)和迭代器(iterator)來說,雖然均非Ruby首創(chuàng),但其語法最為賞心悅目。類似的例子比比皆是。然而真正讓Ruby變得炙手可熱的是web應(yīng)用框架 Ruby on Rails(RoR)的成功,它們還催生了Java平臺(tái)上的Groovy語言和Groovy on Grails框架。RoR奉行的CoC (Convention over Configuration)和DRY (Don't repeat yourself )原則以及MVC架構(gòu)看似了無新意,但與Ruby結(jié)合之后,便如一只猱身而上靈貓,立刻襯托出Java和.NET大象般的身影。”
逗號(hào)有些懷疑:“框架竟然捧紅了語言,框架真有這么重要嗎?”
“如果Web應(yīng)用中動(dòng)態(tài)頁面較少或業(yè)務(wù)邏輯不復(fù)雜,框架的價(jià)值并不大。以前CGI編程就是往Perl之類的代碼中嵌入HTML代碼,如同Java中的Servlet;PHP則單純地在HTML代碼中插入PHP代碼,如同早期的JSP。沒有MVC,也不管什么三層架構(gòu),更沒有ORM。但是——”冒號(hào)拖了個(gè)轉(zhuǎn)折音,“一旦業(yè)務(wù)邏輯變得復(fù)雜,開發(fā)人員增多,手工作坊式編程開始捉襟見肘,引入框架這個(gè)流水生產(chǎn)線來提高生產(chǎn)力便是大勢(shì)所趨。”
句號(hào)不解:“我想Perl、Python和PHP一定也有不少框架,Java中的框架更是泛濫成災(zāi),何以獨(dú)獨(dú)RoR脫穎而出?”
冒號(hào)作出分析:“各種web應(yīng)用框架是不少,但在RoR之前輕量級(jí)套餐式解決方案并不多。Perl中的Catalyst、Python中的Pylon還有PHP中的CakePHP等都是效仿之作。此外,Perl和PHP由于過于流行,反而有不少的歷史包袱,人們習(xí)慣了將表示邏輯和業(yè)務(wù)邏輯編織在一起。至于Java企業(yè)解決方案,框架太多,搭配組合更多,增加了選擇的難度。即使采用最常見的Struts+Spring+Hibernate組合,維護(hù)起來也比RoR繁雜得多。”
嘆號(hào)愈發(fā)擔(dān)憂:“聽這意思,Java還是危險(xiǎn)啊!”
“言之過早。”冒號(hào)不以為然,“首先RoR還有待進(jìn)一步檢驗(yàn),目前無論是應(yīng)用廣度還是深度上尚無法與Java相提并論;其次Java在性能、安全等方面還是有不少優(yōu)勢(shì),而這些對(duì)于大型和關(guān)鍵性的應(yīng)用來說尤為重要。即使在中小型web應(yīng)用中,RoR較之PHP還遠(yuǎn)為不及。”
問號(hào)接下話題:“PHP為何如此流行?”
“因?yàn)樗?jiǎn)單、專一。”冒號(hào)答得很干脆,“與Python和Ruby一開始就定位通用語言不同,PHP是專為網(wǎng)絡(luò)而生的。同早期的Perl相似,PHP起初主要起文本過濾器的作用,只不過Perl多處理文件流(file stream),而PHP多處理套接字流(socket stream)。PHP的語法簡(jiǎn)單,且為網(wǎng)絡(luò)應(yīng)用度身定造,受到網(wǎng)絡(luò)開發(fā)人員的追捧當(dāng)在情理之中。但它實(shí)用而不完美,比如:變量名大小寫敏感而函數(shù)名大小寫不敏感;函數(shù)命名規(guī)則不一致;不支持namespace和unicode;與Perl一樣,它的對(duì)象模型不是先天的,直到PHP 5才真正完善;對(duì)線程支持不足;相比Perl、Python和Ruby,它的功能稍顯單薄等等。”
引號(hào)突然想起:“我記得您在第一堂課提到PHP還能用于桌面應(yīng)用。”
“不僅PHP,Perl、Python還有Ruby,都能作為前臺(tái)語言來開發(fā)命令行或圖形界面的應(yīng)用。同樣地,VB、Delphi和JavaScript也能作為后臺(tái)語言。現(xiàn)代語言都趨向通用化和全能化,以爭(zhēng)取更多的生存空間。”言及于此,冒號(hào)收住話題,“語言簡(jiǎn)評(píng)該告一段落了,現(xiàn)在請(qǐng)大家每人寫一句對(duì)本節(jié)課的感言。”
眾人沉思片刻,揮筆而就——
嘆號(hào)——沒有最好的語言,只有最合適的語言。
逗號(hào)——沒有糟糕的語言,只有糟糕的程序員。
問號(hào)——沒有一種語言是萬能的,只會(huì)一種語言是萬萬不能的。
引號(hào)——廢除對(duì)語言的宗教信仰,建立對(duì)語言的哲學(xué)思維。
句號(hào)——編程就是在人腦和電腦之間尋找最佳平衡點(diǎn)的過程。
冒號(hào)讀罷大悅,順手一掌拍出五記馬屁:“精彩之極!可謂字字珠璣、句句聯(lián)璧啊。茲決定,給諸位的獎(jiǎng)賞是——下課!”
眾人欣然領(lǐng)賞而去。