天天看點

《程式設計語言——實踐之路》讀後感

如果你在試用了28種開源架構和69種eclipse插件後仍不清楚自己眼前的垃圾代碼該如何“重構”,那麼,你也許需要抽出一些時間,補習一下你曾經極度蔑視的、看起來沒有任何“用處”的基礎知識了...

[ 檢視本指南所提及的書籍 ]

再教育?沒錯。依個人愚見,大多數中國程式員都需要接受一次有關程式設計語言的再教育,而Michael L.Scott所著的《程式設計語言——實踐之路》則可以成為這次再教育中的最好讀本之一。

  在現代漢語中,沒有什麼詞比“急功近利”更能展現當代程式員對于程式設計語言的期望和要求了——我見過太多太多隻學會

了“Hello,World ”就打算獨立編寫企業級應用的速成者,我也見過太多太多剛掌握了一門面向對象語言的文法就宣稱自己是OO專家的神仙級人物;在他們眼中,一本名為《某某語言入門》的教科書應足以取代《資料結構》、《編譯原理》、《離散數學》等所有“高深”而“無用”的課程,而一名能熟練使用Hibernate或 Spring的Java程式員就足以成為一家小型企業的J2EE首席架構師了。

  更為有趣的是,這些急功近利的“語言萬能論”者一方面會把某種最流行的語言或類庫當作克敵制勝的惟一法寶,另一方面卻又絲毫不理會那些經過數十年的積澱才成為現代程式設計語言精華的,貫穿于文法、語義和語用等三個層面的基本理念和基本特征;這種做法就像是把一部夏利引擎、麥凱倫外殼的賽車開上了F1賽道,難免會在殘酷的現實面前落得個鼻青臉腫的結局。

  很顯然,如果你對自己在實際工作中總是無法提高編碼效率、無法改進軟體品質的事實困惑不已,如果你在試用了28種開源架構和69種 eclipse插件後仍不清楚自己眼前的垃圾代碼該如何“重構”,那麼,你也許需要抽出一些時間,補習一下你曾經極度蔑視的、看起來沒有任何“用處”的基礎知識了。對于那些沒時間重溫大學課程的上班族來說,這種補習最好從《程式設計語言——實踐之路》開始。即便不能把這本八九百頁的“大部頭”全部讀完,你也至少能在閱讀過程中明白三個看似淺顯、實則微妙的“大道理”:

  其一,語言必須與環境相結合,才能發揮出最大的功用。這裡所說的 “環境”通常包括編譯環境、運作環境和應用環境三個方面。舉例來說,如果你打算仿照着某些開源架構的做法,使用控制反轉和依賴注入技術消除代碼中某些讓人生厭的依賴關系,你一定會認真研習實作類似技術的文法特征,但你未必會主動思考以下幾個問題:在編譯層面,使用了這些文法特征的代碼是否會影響到最終生成的目标代碼品質?在運作層面,該如何組織這些文法特征,才能讓使用了相關技術的可執行程式在支援廢料收集的并發環境下有不俗的表現?在應用層面,這些旨在消除依賴關系的技術會不會破壞新、舊子產品間的平衡關系,以至于我們必須花上大量時間改寫原有的代碼或接口才能保證系統的平滑更新?全面思考這些與環境相關的問題并不一定會改變你的抉擇,但它卻可以幫助你找到效率、可靠性和可用性之間的最佳平衡點。在此方面,《程式設計語言——實踐之路》一書所使用的,将程式設計語言與編譯原理、面向對象等知識綜合起來、融會貫通的做法不但可以節省我們分類學習的大量時間,還可以訓練我們從整體出發、多角度思維的方式與方法,其價值不言而喻。

  其二,程式設計語言本身所具有的多樣性可以成為我們提高軟體開發水準的最佳指南。說到這裡,我又想起了那些充斥在各大技術網站的,題為“某某語言比某某語言更強大”或“某某語言已死,某某語言必勝”的文章。發表這些文章的帖主也許并不懂得,程式設計語言的世界本來就是一個多樣化的、五彩缤紛的世界,每一種成功進入應用、教學或科研領域的程式設計語言都有它值得學習和借鑒的地方。如果僅僅根據個人的喜好或是響應時尚的号召,就盲目地吹捧某一種語言并貶低其他所有語言,這樣的文章和那些頻繁出現在Fans網站上的“愛死某某某,恨死某某某”的文章有什麼本質的不同?更為重要的是,如果我們能夠在《程式設計語言——實踐之路》的指下,真正懂得了函數式語言、資料流語言、邏輯式語言、馮·諾伊曼語言、面向對象語言等不同的語言類型在文法設計、編譯器設計和運作環境設計方面的異同,我們就會驚訝地發現:Scheme語言的lambda表達式可以在C 語言中優雅、高效地解決諸如面向契約設計之類的複雜問題;Ada95語言中提供的同步和保護機制可以為那些使用Java編寫的多線程應用提供重要的參考; Smalltalk語言與編譯和運作環境的緊密結合則可以為我們設計可擴充的JavaScript宿主提供最好的借鑒……從這個意義上說,學習一種語言的意義絕不在于為自己增添一種求職和謀生的手段——真正善于學習的人總能從每種語言的設計和實作中找到許多可用于提高程式設計水準的關鍵特征。

  其三,使用特定語言編寫出來的代碼是否優雅、可靠,這主要取決于程式員對各種基本理念和基本原則的認知程度,而不取決于程式員記住了多少複雜的文法特征或學會了多少流行類庫的用法。正如《程式設計語言——實踐之路》所說的那樣,“典型的C 程式員都極少使用聯合、多重繼承、變動個數的參數,或者. 運算符”,但是,如果你了解了隐藏在這些複雜文法特征背後的東西——如記憶體空間的配置設定和尋址方式,複本式繼承和共享式繼承之間的關系,參數傳遞和求值順序,動态方法限制和成員查找,等等——你就可以在需要使用這些文法特征的時候滿懷信心地告訴自己:“嘿,這不過是某某原則或某某技術在C 語言中的表現形式罷了,我能搞定它!”反之,如果你不曉得與資料結構和算法相關的代碼在編譯、運作時必然存在的各種均衡與折中問題,即便你把C 語言的标準文檔背得滾瓜爛熟,即便你可以默寫出System.Collections命名空間中的所有屬性和方法,你也會在體驗過自己開發的軟體與成熟軟體之間的差别後大發感慨:“同樣是使用C 語言,為什麼我寫的程式總會從頭到腳散發着‘業餘’的氣味兒呢?”

  關于程式設計語言的本質,Michael L.Scott是這樣說的:“就像自然語言限制着人們解釋和論述的方式一樣,程式設計語言也限定了什麼可以表達,什麼不能表達,并對程式員能夠怎樣思考問題有着深刻而微妙的影響。”既然如此,我們還猶豫什麼呢?與其後悔在學校中虛度了光陰,還不如馬上捧起《程式設計語言——實踐之路》這本書,接受一次有關程式設計語言的再教育呢!

繼續閱讀