天天看點

(轉)侯捷先生的書評

作者簡介:侯捷,台灣電腦技術作家,着譯評兼擅。常着文章自娛,頗示己志。

個人網站:www.jjhou.com

北京鏡站:www.csdn.net/expert/jjhou

●開場白

《程式員》雜志邀我開一個專欄。我向來期待一本為程式員打造、以程式員為主體對象的刊物,是以這樣的邀請很難推卻。再加上蔣濤先生與我的私交,我於是要求自己,盡可能撥出時間來為《程式員》寫稿。專欄可以開,能不能全無間斷則不敢保證。

大陸讀者對我肯定陌生,容我簡介自己。我是一名資訊教育工作者,寫譯書籍,教育訓練業界人員,主持網站回應讀者與學員,并於大學開課。進入教育領域之前,我分别擔任過台灣工業技術研究院機械所和電通所的副研究員和特約研究員,分别研發 CAD/CAM 軟體和 Windows 多媒體系統。有人戲稱工研院為少林寺 ─ 位在山上,男多女少,高手如雲,藝成下山闖蕩江湖者不計其數。

寫這篇稿子的此刻,我投入教育領域正好十年。這是一條科技人很少想過的路子,於我也是生命中一個不經意的轉彎。不過,這種迥異於軟體研發也迥異於象牙塔教學的生涯,實在是多彩多姿,與讀者的互動尤其曼妙無比。

我的鑽研領域,前七年都在 Windows 程式設計方法和作業系統原理,近三年則放在更基礎的、與平台無關的層面。

●書籍是永遠的良師益友

過去十年中,有一件事最是奇特有趣:我於 1993 開始《無責任書評》專欄,介紹我所能夠掌握的技術範圍内的一些世界名着。這樣的題材與文體,吸引了很多目光,也開創了某種先河。《無責任書評》夾雜對台灣 電腦出版業的觀點與評論,由於當時台灣電腦書的良窳程度極端不均(現在也是),初階 濫而高階貧血(現在也是),我以程式員的角度所給的評論顯得尖銳不群。

1998 年網際網路興盛,我把所有電腦散文都移到網路上發表,範圍擴及學習方向與學習态度(但不涉及細節技術)。過去的書評文章也重新整理了起來。各位可從侯捷網站上看到所有這些文章。

書評之是以受人歡迎,一方面在它的知識性,一方面在它的辛辣味。通常我的原則是隻評好書(該說是「薦」而不是「評」了),是以辛辣味隻藏在旁徵博引的明喻 暗諷之中,或偶爾忍不住的一把火。一般而言,隻要有豐富的知識含量,而不是單純地将章節照錄一遍,書評專欄就夠吸引人了,辛辣味隻是附帶紅利。諸君如想嘗 嘗真正的川辣子,看看國外期刊的書評,肯定叫溫良恭儉讓的中國人頻頻撫胸,大驚失色。

好書之於學習(尤其是自修),重要性自不待言,是以書評永遠受歡迎。好書是一支釣杆,好書評則讓你認識這支釣杆并告訴你到哪兒去買。單一書評固然好,如果 能系列化、系統化、根據技術的演進與層次,鋪陳一條學習的紅地毯,就更有價值。過去我曾經分篇為台灣讀者介紹過 C++/OOP 方面的許多好書。做為本專欄的第一篇,我決定将它們彙總結集,讓你一次看飽買足。

●閱讀之前

往下閱讀之前,我想先談一些打底的話。

第一,以下介紹的全都是外來書。各位購買這些書籍或許有經濟壓力,但畢竟它們都是成名已久的世界名着,我想,為讀者開這扇窗絕對是很重要的。

購買這些書籍其實很友善,隻要你有信用卡,連上亞馬遜網路書店(www.amazon.com)愛怎麽買就怎麽買。我們的困難可能在於信用卡和書價。唔,加上運費真的很貴。

第二,在我少不更事的時候,讀了一本好書并不會回頭特别記下作者姓名。這是個絕對錯誤的态度。茫茫書海中該如何選書?第一次當然是到書店去亂槍打鳥,浪費 一點子彈。但是你不能老停留在少不更事的階段,你的子彈還有你的書架空間都很寶貴,你的時間更寶貴。牢記優秀作家的名字,是找好書的捷徑。這其實也是寫閱 環境的一個進步表徵:讓好作家有自己的品牌。

第三,OO(Object-Oriented,物件導向)領域,從程式設計到設計,可概分為 OOP(Progrmming)、OOA(Analysis)、OOD(Design)。目前國外十分成熟的 UML(Unified Modeling Language)屬於OO 領域裡頭用來将設計概念表現出來的一種 notation(符号表現法)。本篇文章隻介紹到 OOP 這個層次(唯 [Gamma95]稍屬例外),這比較具體,也比較貼近大部份程式員。愈往上去愈抽象,愈接近軟體工程或方法論。

第四,以下介紹的這些 C++/OOP 書籍,幾乎成為我初步判斷一個人在這方面水準的基準。一個具備數年經驗的 C++ 程式員,或許自己能夠摸索出「總是讓 base class 擁有 virtual destructor」這樣的準則,但初出茅廬的程式員,恐怕連 virtual destructor 是什麽都不甚有概念,更别說該如何正确運用它。如果他說他看過 [Meyers98],我會比較放心他的水準。

有趣的是,我曾經在自己班上(學生從大二到研究所學生都有)做了一個調查。擁有這些書籍的學生人數并不多,而且老是同樣幾位。這讓我感覺,強者恒強弱者恒弱, 悲夫。就我和業界的廣泛接觸經驗,我也發現,許多程式員離開學校後就不太看書了,或者因為忙碌,或者因為安於現況。專案做了不少,技術卻沒有精進太多。三 兩下招數一再用老,人特别容易空乏。請你打開這扇窗,你會發現巨着之是以為巨着,專家經驗之是以為專家經驗,是有道理的。愈是看了這些書,你愈會發現這些 書的價值,并覺醒過去的一些愚蠢行為。

第五,下面開出來的書單都是我熟讀過的,其中甚且不少繁體中文版是我翻譯的,是以我放心推薦并接受質詢。然而書海浩瀚,遺珠難免。

第六,為求友善,以下以學術界習慣的标示法,标示書籍代名。文中即使用這些代名。凡有中文版者,我會特别加注。

[Ellis90]: The Annotated C++ Reference Manual, by Margaret A. Ellis and Bjarne Stroustrup, Addison-Wesley, 1990. 447 pages.

(轉)侯捷先生的書評

[Gamma95]: Design Patterns: Elements of Reusable Object-Oriented Software,

by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides, Addison-Wesley, 1995. 395 pages

簡體中文版:《設計模式》,李英軍等譯,機械工業出版社,2000. 254 頁

(轉)侯捷先生的書評

[Lippman98]: C++ Primer, 3rd Editoin, by Stanley Lippman and Josee Lajoie,

Addison Wesley Longman, 1998. 1237 pages.

繁體中文版:《C++ Primer 中文版》,侯捷譯, 峰 1999. 1237 頁

(轉)侯捷先生的書評

[Lippman96]: Inside the C++ Object Model, by Stanley Lippman, Addison Wesley Longman, 1996. 280 pages

繁體中文版:《深度探索 C++ 物件模型》,侯捷譯, 峰 1998. 320 頁

(轉)侯捷先生的書評

[Meyers96]: More Effective C++, by Scott Meyers, Addison-Wesley, 1996. 318 pages

繁體中文版:《More Effective C++ 中文版》,侯捷譯,培生 2000. 318 頁

(轉)侯捷先生的書評

[Meyers98]: Effective C++, Second Edition, by Scott Meyers. Addison Wesley Longman, 1998. 256 pages

繁體中文版:《Effective C++ 2/e 中文版》侯捷譯,培生 2000. 256 頁

(轉)侯捷先生的書評

[Struostrup97]: The C++ Programming Language, 3rd Editoin, by Bjarne Stroustrup, Addison Wesley Longman, 1997. 910 pages

繁體中文版:《C++ 程式語言經典本》,葉秉哲譯,儒林 1999.(未錄總頁數)

(轉)侯捷先生的書評

[Sutter99]: Exceptional C++, by Herb Sutter, Addison Wesley Longman, 2000. 208 pages

繁體中文版:《Exceptional C++ 中文版》侯捷譯,培生 2000. 248 頁

(轉)侯捷先生的書評

●層級一:文法/語意(C++)

學習語言,當然首先從文法開始。初學者究竟要從輕松獨幕喜劇出發,或一開始就接觸巨着,殊無定論,因為初學者有很多種,「初學者」一詞卻無法反映他們的真實狀态。我的學生群中有 13 歲的,也有 31 歲的(年紀更大的當然也有),有人連電腦基本概念都尚未建立,有人已是經驗豐富的軟體工程師。不同背景、不同年齡、不同領悟力、不同學習速度的人,需要不同層級的教材來滿足他們。同一個人在不同階段,也需要不同層面的教材來提升其功力與視野。

但,不論新生或老手(新生有一天會變成老手),任何一位C++ 程式員,我都強烈建議你的書架上要有 [Lippman98] 和 [Struostrup97] 這兩本書。它們是 C++ 文法/語意層面的百科全書;所有相關問題,這兩本書都是最後仲裁,說了算!它們不适合連電腦基本概念都缺乏的人,但頗為适合已有程式設計經驗的人。

這兩本書都已經在 C++ 領域馳逞十年。最新版本都是第三版,印映 1998 定案的 C++ 标準規格。由於 C++ 标準規格帶入一個十分龐大的标準程式庫,是以這兩本書也都比其前一版有巨幅的改變。如果要拿這兩本書做特性比較,我的個人觀感是,[Lippman98] 适合做為教本,教學自修叁考皆宜,[Struostrup97]比較生澀難讀,學術味重,叁考性濃厚,權威性最高(畢竟 Struostrup 創造了 C++)。

這兩本書的每一版壽命大約是五年。C++ 标準規格定案後,國際标準組織(ISO)每五年開會覆審一次,是以第三版至少也是五年壽命。也許有人以為,做為疑問辯論的最終裁判,還是以 C++ 規格書為準(1998/09/01 出版,編号 ISO/IEC 14882),而且網路下載下傳隻需 18 美元,PDF 格式,索引極為友善。這當然是很好的一份工具,但是這份檔案絕不适合做為學習材料,太硬了。

目前全世界還沒有任何一個 C++ 編譯器支援完整的 C++ 标準規格,互有長短,是以晚近新增的語言特性,不見得能夠在你手上的編譯器演練。關於 Visual C++, Borland C++, CYGNUS C++ 三套工具在C++ 标準規格上的表現,我個人有一些經驗,整理於http://www.jjhou.com/qa-cpp-primer-27.txt。為什麽遲遲未有完全支援标準規格的 C++ 編譯器問世呢?因為這已經不成為市場競争重點;C++ 開發工具市場已經轉到對視窗介面的支援以及對企業的完整解決方案。

這兩本書深具工具叁考價值,是以索引格外重要。兩本繁體版譯本皆用心地制作了索引(仍以英文術語來排列),此可為大陸借鏡。中文電腦書帶有索引,在台灣亦 不常見,兩本譯本皆因譯者的特别用心才得如此。索引采用英文術語,導出一個問題:如果書内文本沒有保留英文術語,怎麽辦?索引的制作與配套辦法,是科技翻 譯亟需深思的一個問題。我的作法是,把諸多科技術語保留原文不譯,并努力維持中英頁頁對照,這麽一來原書索引就可以完整而輕松地保留下來。保留原文術語不 譯,不完全是為了索引的制作,而是因為某些字眼強譯為中文,不但與業界習慣脫節,也與世界脫節。我所采行的這種作法受到很多讀者的喜愛,但是哪些原文術語 要保留,哪些要中譯,又是見仁見智。大凡如果譯者真正是業内人士,他的選擇不會脫離業界習慣太遠。

●層級二:專家經驗(C++/OOP)

能夠在學習文法并開始練習程式設計的同時,就接觸專家的經驗,最是理想,但實際上很難如此。一方面,每一條經過淬煉的程式設計規則,其來龍去脈可能牽涉到多方面的 知識,甚至可能涉及底層技術,這對新手的負擔過重。另一方面,初學者往往隻顧眼前半畝田,眼光沒太高遠。不過,如果有良師帶引,依樣畫葫蘆不失為一種初期 的權宜學習方式。

無論如何,為了提升自己的 OOP 功力,專家經驗是一條終南捷徑,讓你一次吸取高手十數年功力。[Meyers96] 和 [Meyers98] 是我極為推薦的兩本專家經驗書。以下試摘書中條款數例,諸君可掂掂自己的斤兩,看看自己平時實踐了多少,從各條款中又聯想了多少。

⊙以下摘自 [Meyers98]:

條款1:盡量以 const 和 inline 取代 #define

條款2:盡量以 <iostream> 取代 <stdio.h>

條款3:盡量以 new 和 delete 取代 malloc() 和 free()

條款5:使用相同型式的 new 和 delete

條款6:記得在 destructors 中以 delete 對付 pointer member

條款7:為記憶體不足的狀況預做準備

條款8:撰寫 operator new 和 operator delete 時,應奉行慣常行為

條款9:避免遮掩了 new 的正規型式

條款10:如果你寫了 operator new,請對應寫一個 operator delete

條款11:classes 内如果動态配置記憶體,請為它宣告一個 copy constructor 和一個 assignment 運算子

條款12:在 constructor 中盡量以 initialization 動作取代 assignment 動作

條款13:initialization list 中的 members 初始化排列次序應該和其在 class 内的宣告次序相同

條款14:總是讓 base class 擁有 virtual destructor

條款15:令 operator= 傳回 *this 的 reference

條款16:在 operator= 中為所有的 data members 指派。

條款17:在 operator= 中檢查是否「自己指派給自己」

條款19:區分 member functions, non-member functions 和 friend functions 三者

條款20:避免将 data members 放在公開介面中

條款21:盡可能使用 const

條款22:盡量使用 pass-by-reference(傳址),少用 pass-by-value(傳值)

條款23:當你必須傳回一個 object 時,不要嘗試傳回一個 reference

條款29:避免傳回内部資料的 handles

條款30:避免寫出「傳回 non-const pointers 或 references 并以之指向較低存取層級之 members」的 member functions

條款31:千萬不要傳回「函式内的 local 物件的 reference」,或是「函式中以 new 獲得的名額的所指物件」。

條款32:盡可能延緩變數定義式的出現

條款33:明智地運用 inlining

條款34:将檔案之間的編譯相依關系(compilation dependencies)降至最低

條款35:确定你的 public inheritance 模塑出 "isa" 的關系

條款36:區分「介面繼承(interface inheritance)」和「實作繼承(implementation inheritance)」

條款37:絕對不要重新定義一個繼承而來的非虛拟函式

條款38:絕對不要重新定義一個繼承而來的預設叁數值

條款39:避免在繼承體系中做 cast down(向下轉型)動作

條款40:透過 layering(分層技術)來模塑 has-a 或 is-implemented-in-terms-of 的關系

條款41:區分 inheritance 和 templates

條款42:明智地運用 private inheritance(私有繼承)

條款43:明智地運用多重繼承(multiple inheritance,MI)

條款45:知道 C++(編譯器)默默為我們完成和呼叫哪些函式

條款47:使用 non-local static objects 之前,确定它已有初值

條款49:盡量讓自己熟悉 C++ 标準程式庫

⊙以下摘自 [Meyers96]:

條款1:仔細差別 pointers 和 references

條款2:最好使用 C++ 轉型運算子

條款3:絕對不要以 polymorphically(多型)方式來處理陣列

條款4:非必要不使用 default constructor

條款5:對自定的型别轉換函式保持警覺

條款6:差別 increment/decrement 運算子的前序(prefix)和後序(postfix)型式

條款7:千萬不要多載化 &&, ||, 和 , 運算子

條款8:了解各種不同意義的 new 和 delete

條款9:利用 destructors 避免遺失資源

條款10:在 constructors 内阻止資源遺失(resource leaks)

條款11:禁止異常訊息(exceptions)流出 destructors 之外

條款12:了解「丢出一個 exception」與「傳遞一個叁數」或「呼叫一個虛拟函式」之間的差異

條款13:以 by reference 方式捕捉 exceptions

條款15:了解異常處理(exception handling)的成本

條款17:考慮使用 lazy evaluation

條款18:分期攤還預期的計算成本

條款19:了解暫時物件的來源

條款20:協助完成「傳回值最佳化(RVO)」

條款21:利用多載化技術(overload)避免隐式型别轉換

條款22:考慮以運算子的複合型式(op=)取代其獨身型式(op)

條款24:了解 virtual functions、multiple inheritance、virtual base classes、

runtime type identification 所需的成本

條款25:将 constructor 和 non-member functions 虛拟化

條款26:限制某個 class 所能産生的物件數量

條款27:要求(或禁止)物件産生於 heap 之中

條款28:Smart Pointers(精靈名額)

條款29:Reference counting(叁用計數)

條款30:Proxy classes(替身類别、代理人類别)

條款31:讓函式根據一個以上的物件型别來決定如何虛拟化

條款33:将非尾端類别(non-leaf classes)設計為抽象類别(abstract classes)

其中條款25~31層次甚高,用來解決C++ 軟體開發過程中一再出現的問題,作者把這類問題及其解法稱為 idioms(慣用法)或 patterns(樣式),與着名的23個精典 patterns(見 [Gamma95])相呼應。雖然這裡所談的規模格局部都比較小,但正因為如此,作者得以完成比較具體的實作,反而比 [Gamma95] 容易閱讀。

[Meyers96] 和 [Meyers98] 這兩本書成名已久,獲得極大的聲譽。以下的贊美可以使你更了解這兩本書的性質和價值:

◆在你開始着手第一個真正的 C++ 專案之前,你應該閱讀本書;在你獲得一些實務經驗之後,你應該再讀一遍。-- comp.lang.c++

◆作者不隻提供你撰寫 C++ 碼時應該遵循的明白規則,也提供了深入的解釋與範例。-- Sun Expert

◆每一位 C++ 程式員不隻應該擁有這本書,而且應該确實運用這本書。書中文字極易拿來實際運用,交叉叁考與索引的功夫做得很好。-- Computer Language

◆這本絕妙好書提供的招數,幫助我們把 C++ 運用得更好。每一位 C++ 程式員桌上都應該有這本書。在提升 C++ 程式設計的整體品質上, Scott Meyers 這份珍貴的禮物或許比業内任何人士的貢獻都大。-- Jesse Liberty, C++ Report

[Sutter99] 是另一本專家經驗談。作者是 C++ Report 期刊主編,并主持網路上一個名為每周之星(a Guru of the Week,GotW)的 C++ 特别節目。以他的背景和經曆,接觸的疑難雜症自然是又多又猛。這本書整理了 47 個條款,由於條款名稱無法表現某種具體準則,是以我不條列於此。本書主要分為八大項:

1. 泛型程式設計與 C++ 标準程式庫

2. Exception-Safety(異常發生時仍安全)的主題與相關技術

3. Class 的設計與繼承

4. 編譯器防火牆(Firewalls)及 Pimpl 慣用手法

5. 名稱查詢、命名空間、介面原則

6. 記憶體管理

7. 陷阱、易犯錯誤與有害作法

8. 雜項主題

Scott Meyers 為此書所寫的序,點出了這本書的特質:

『從語言的特性到标準程式庫内的元件,再到程式編寫技術,本書在不同的主題之間跳躍,總是使你稍稍失去平衡,總是使你必須付出全然的注意力。...我把 GotW 發音為 "Gotcha"(意思是「這下可逮到你了」),或許很适當。當我把書中測驗的(我的)答案拿來和 Sutter 的答案比較,我掉進他(和 C++)鋪設的陷阱中 ─ 雖然我實在不想承認這點。我幾乎可以看見 Herb 微笑并溫柔地對我所犯的每一個錯誤說 "Gotcha!"。...當你選擇 C++ 做為工具,你必須小心地思考你正在做些什麽。C++ 是一個威力強大的語言,用來協助解決吃力的問題,其重要性使你必須盡可能面對語言本身、程式庫、程式慣用手法來磨煉你的知識。』

就我的英文程度而言,[Sutter99] 讀起來不若 [Meyers96] 和 [Meyers98] 那般平順,原因是其中用了很多厘語、口語、典故。舉個例子,Morphy law 是什麽,大家知道嗎?(莫菲定律說:會出錯的,一定會出錯。)Machiavelli 又代表了什麽意思?(意大利政治家,以詐術聞名。)

這類專家經驗談,多半薄而貴,但貴得有價值。好消息是,[Meyers96] 和 [Meyers98] 已經集結為電子書,以光碟呈現,采用 HTML 格式,可使用任何支援 Java(以便進行全文檢索)的浏覽器閱讀。多少錢一片?請上亞馬遜瞧瞧。

(轉)侯捷先生的書評

●層級三:底層機制(C++ Object Model)

如果對於迥異傳統程式設計方式的 C++ 特性,諸如 virtual functions、constructors、destructors┅等特異功能一直無法心領神會,可能有必要到内部機制去深度遊曆一番。不要以為鑽 到這麽深層的技術,會愈搞愈糊塗,愈搞愈恍忽。很多人,包括我自己,是在遊曆過底層機制一遍之後,才徹底覺悟并接受了 C++。

所謂底層機制主要是指 (1) object 的記憶體布局:data members 分布在哪裡?加了 static 又如何?member functions 分布在哪裡?加了 virtual 又如何?有了繼承又如何?(2) constructors 和 destructors為什麽會自動被喚起?(3) template 模闆機制是怎麽回事?(4) this 名額是怎麽回事?(5) runtime type identification(RTTI)是怎麽實作出來的?

知道了這些底層機制,你便能夠對自己在 C++ 程式中的每一個動作所引發的影響,了如指掌。學習這些底層技術,不是為了自行開發一套編譯器,而是為了徹底掌握 C++ 語言;底層技術的學習,隻是過程,不是目标。這種情況和《深入淺出 MFC》(侯捷着,松崗 1997)的情況很像,數萬名讀者不是為了自行開發 framework 而歡喜閱讀該書對 MFC 的剖析,是為了徹底掌握自己在撰寫 MFC 應用程式時的一言一行。

底層機制方面的專論書籍非常稀少。我所僅見的兩本,一是 [Ellis90],一是 [Lippman96]。前者被昵稱為 ARM(帶注解的叁考手冊),是早期 C++ 編譯器的實作依循準則,但因年代過遠,我甯願更推薦後者。[Lippman96] 筆誤非常多,我翻譯此書的過程中至少修正了100 個以上的筆誤。

了解事務的本質,到底有沒有必要?這個問題太簡單了:如果你必須走那麽一遭,才能接受事務的表徵,那麽於你就有必要。如果你天生是個 OO 奇才,或你一開始接觸的第一個語言就是OO 語言,以至於有可能認為其中的一切都是理所當然,可以完全領受各種特性的運用,那麽底層機制於你就不需要。

我個人是如此地真正第一線面對大量的學習者,就我的教學經驗(乃至於我個人的學習經驗),我要說,了解事務的本質,對絕大多數人都有極正面的幫助。關於這一點,我最喜歡引用林語堂先生在《朱門》一書裡頭的一句話:『隻用一樣東西,不明白它的道理,實在不高明。』

●層級四:設計觀念的複用(C++/Patterns)

軟體工程的所有努力,無非是為了美好的複用性(reusibility)。從早期的subroutines, procedures, functions, 到後來的 classes, templates。在在為了相同的目标。如今我們已經能夠将「資料,以及處理資料的動作」封裝得很好,甚至能夠把資料型别都抽取出來成為叁數,甚至更進 一步将資料本體和處理資料的各種演算法獨立開來,各自發展而又能夠藉着某種「黏膠」彼此作用(注)。

注:這便是所謂泛型程式設計(generic programming)的精神。下個月我為大家介紹這個主題。

很好,很好。但是長久以來我們卻無法将設計概念以規格化的方式傳承下去。面對資料結構(data structures),我們隻要說 stack, queue, list, 不必多言,聞者馬上就知道stack 是先進後出,queue 是先進先出,list 是單向或雙向串鍊。面對演算法(algorithms),我們隻要說 quick-sort 和 binary-search, 不必多言,聞者馬上就知道其複雜度分别是 O(N log N) 和 O(log N),其行為模式如何如何。但是當我們希望保證某個 class 在整個系統中隻有一份 object 時,該如何設計?當我們希望對某個 object 架構出一個替身(或說代理人)以控制對本尊的存取(進而達成緩式評估lazy-evaluation)時,該如何設計?當我們希望以某種方法走過某個聚合 物件内某一範圍的所有元素,而不需曝露該物件的底層結構時,該如何設計?當我們希望以共享方式來處理系統中的基本元素(例如龐大文檔内數量相對極少的基本 字元)時,該如何設計?

如果這些一再被反覆大量運用、并且早經衆人淬煉出極佳作法的設計(一整組解決方案),能夠系統化地分類整理,給定标準名稱、定義、效果、實作法、甚至示例代碼,我們就不必每次都從輪子造起(還造得不比專家圓呢)。如果程式員之間隻要說Singleton, Proxy, Iterator, Flyweight,聞者馬上知道其背後代表的是某種特定設計,有着特定的邏輯,用以解決某種特定問題,可多好。這正是将設計觀念及其實作邏輯的寶貴經驗,以簡潔而可複用的形式表達出來。

[Gamma95] 一書内含精心整理的 23 個 design patterns。四位作者的主要貢獻不在於 patterns 的建立,而在於 patterns 的整理形式與發揚光大。書中所提的 patterns 名稱,幾乎已經成為 OO 設計領域裡頭的标準辭彙。《程式員》去年 11 月份有一份蔣濤先生針對 [Gamma95] 的評論,其中對於 patterns 的比喻,令人激賞:『patterns 需要反複練習體會,才能應用自如。這有點像圍棋中的定式,圍棋定式是百年來高手下法的總結,但不能簡單地應用,要看場合選擇合适的定式,還要按棋理變通下法。』

幸運,真幸運,[Gamma95] 也有電子書出版,以光碟呈現,采用 HTML 格式,可使用任何支援 Java(以便進行全文檢索)的浏覽器閱讀。

(轉)侯捷先生的書評

原帖位址:http://jjhou.csdn.net/programmer-1-cpp&oop.htm

程式設計究竟是一門工匠技藝還是一門藝術?都可以是!看你從哪個角度出發。有人說連設計概念都可以以 patterns 規格化地傳承,還談什麽藝術?如果你是這樣想,我說三件事給你聽。建築是一門技術還是藝術?很多人都認為建築是一門藝術。然而 patterns 的概念正是濫觞於建築設計領域。目前軟體界所使用的 pattern 一詞源自建築理論大師 Christopher Alexander 的着作,他的書探讨的雖然都是建築設計與都市規劃的課題,但其精神與本質卻适用其它領域,包括軟體開發。另一件事是,軟體界開始流行 framework 工具時,也有人認為程式主架構都被限死了,談什麽設計與彈性?我說:隻要饅頭好吃,我從不在乎是機器饅頭還是純手工精制。你的設計精力應該放在專業領域如 繪圖、影像處理、統計、數學分析┅,而不是放在共通的基礎架構上。如果你真的對基礎共通的事務感興趣,你不應走應用軟體開發之路,應該将設計天份用來研究 更新更好的資料結構,更新更好的演算法,更新更好的架構。

●線性學習?沒的事!

雖然我把 C++/OOP 的學習階段分為四層,但除了第四層得萬事俱備才能水到渠成,其他三層的學習并不是那麽泾渭分明。通常你要你的C++ 堅轫鋒利,你得讓它曆經多次回火,在高熱和驟冷之間 煉,在學術與實用之間震蕩。我無法為你畫出一條單行道,你勢必得走些回頭路,時而品味一下曾經忽略的小花,時而啜飲一口被你遺忘的甘泉,填實了某種縫隙之後,才能神清氣爽充實盈滿地再出發。

繼續閱讀