原文地址:[點擊打開鏈接](http://blog.csdn.net/jackfrued/article/details/44456495)
最近在網上看了一個非常好的帖子《程序員一生必讀的書》([我的騰訊微博](http://t.qq.com/jackfrued)上有分享該貼子鏈接,有興趣就點擊進去看看吧),該貼的第一個張圖片是一個雷達圖, 這張圖是由ThoughtWorks(全球軟件設計與定制領域的領袖級企業)的資深人士提供的,它將程序員要讀的書分為四個類別,每個類別又分為初級、進階和高級讀物,并用黃色三角形點出了強烈推薦閱讀的書籍。四個類別包括:
- 編程實踐(Coding Practice)
- 設計與架構(Design & Architecture)
- 方法學(Methodology)
- 思想與領導力(Thought & Leadership)

相信這張圖會幫助到很多迷茫的職業人,因為好書就像明燈一樣會照亮我們的方向,那些大師級的人物將他們的經驗分享給我們,真的有如浴春風的感覺。有時候會很感慨國外有那么多厲害的技術作家寫了那么多好的作品,而國產技術書籍中的好書真算得上是鳳毛麟角。有時候也會問自己,能不能做一個技術作家呢,我想我的修煉還遠遠不夠。?
雖然不能夠自己寫一本好書,但是還是很愿意把自己的讀書心得跟大家一起分享,雷達圖上的書我讀過的約有1/3,下面就把讀這1/3的心得跟大家分享。
### Code Complete 《代碼大全》

### Refactoring《重構:改善既有代碼質量》

??如果一個人沒有聽說過《重構》這本書,那么他一定不敢說自己是程序員;如果一個人沒有閱讀過《重構》這本書,那么很難想象他會是一名優秀的程序員。這本書是很多公司要求Java程序員必讀的三本書之一(另外兩本書是《Java編程思想》和《Effective Java》),其實無關編程語言,是程序員就能夠從這本書中受益。?
??這本書我個人最喜歡的第三章 - “代碼的壞味道”,因為我喜歡在寫完代碼后去思考我的代碼中有沒有這些壞味道,然后再去想一想應該如何重構代碼。這本書的作者是世界級的軟件開發大師Martin Fowler,他也被譽為軟件開發“教父”,同時他還是敏捷開發的創始人之一。Martin Fowler編寫了很多極好的書籍,包括《企業應用架構模式》、《領域特定語言》、《NoSQL精粹》、《分析模式:可重用對象模型》等。Martin Fowler給出的代碼的壞味道包括:?
-Duplicated Code(重復代碼):“代碼有很多中壞味道,重復是最壞的一種”,這句話我經常講給自己的學生聽,但是他們真正領悟并踐行這句話的人卻不多。一個類中的兩個方法有重復代碼,那么一定可以通過抽取方法的方式將重復代碼放到另一個方法中以供調用;兩個互為兄弟的子類中如果有重復代碼可以將其重復代碼抽取到父類中;兩個沒有關系的類中如果有重復代碼,那么可以重新抽取一個類將重復代碼放到這個第三方類中。?
-Long Method(長的方法):程序越長理解起來就越困難,這已經是常識了,使用短小的方法首先符合高內聚的要求,同時也可以給通過給方法起一個好的名字來幫助理解方法的作用。如果感覺到方法的某個地方需要注釋來說明什么,那么可以把這些東西放入一個獨立的方法中,并以用途(注意不是實現手法)來命名方法。?
-Large Class(巨大的類):如果希望寫一個類來做很多的事情,那么最終勢必導致重復和混亂的代碼。類的設計應當遵循單一職責原則(SRP)。重構一個巨大的類可以使用抽取接口的方式來搞清楚這個類應該如何分解。?
-Long Parameter List(長參數列表):這個對于做過Windows編程或者用過MFC(Microsoft Foundation Class)的程序員來說再熟悉不過了,Windows函數和MFC中的方法那些長得變態的參數列表對程序員來說都是惡夢。重構的方式很多,比較常見的是將相關的參數組織成一個對象來替換掉這些參數。
-Divergent Change(分散的可變性)和Shotgun Surgery(散彈式手術):這兩種壞味道前者講的是新功能難以加入,后者說的是某種變化會引發多個細節的修改。簡單的說如果程序中的可變因素散落在代碼的各個角落中,那么代碼的維護將是一場惡夢。重構的方法是找到特定原因造成的所有變化,然后將它們抽取到另一個類中。設計模式中的橋梁模式就是為了解決這一問題而提供的解決方案。?
-Feature Envy:這個真沒想到如何翻譯會比較容易理解,簡答的說就是一個方法從另一個類的對象那里獲取許多的值,重構的方案是將該方法移到另一個類中。?
-Data Clumps(數據群集):狀況類似于長參數列表。?
-Primitive Obsession(基本類型偏執)?
-Switch Statements(重復的switch語句):面向對象程序的一個明顯特征就是用多態替換掉switch結構,因為這種switch結構會在多個地方重復。?
-Parallel Inheritance Hierarchies(平行繼承結構):情況跟Shortgun Surgery差不多,可以使用橋梁模式進行重構。?
-Lazy Class(冗余類):如果一個類不值得存在,那么它就應該消失。?
-Speculative Generality(投機通用性):重構方式是如果你的抽象類、委托、方法的參數沒有實際的作用,那么就應當被移除掉。?
-Temporary Field(臨時字段)?
-Message Chains(消息鏈):我個人并沒有感覺到這個有多么壞。?
-Middle Man(中間人):如果一個類的很多功能都通過委托給其他類來完成,那么就不如去掉這些中間人直接和真正負責的對象打交道。?
-Inappropriate Intimacy(過于親密)?
-Alternative Classes with Different Interfaces(異曲同工)?
-Incomplete Library Class(不完整類庫)?
-Data Class(數據類):類的退化結構。我們在分層開發中經常使用的失血模型(事務腳本模式)中的業務實體不就是數據類嗎,這明顯與面向對象的思想是背道而馳的。?
-Refused Bequest(拒絕遺產):如果子類復用了父類的行為,又不愿意支持父類的接口,可以考慮用合成關系聚合關系取代繼承關系來消除這種壞味道?
-Comments(注釋劣質代碼):注釋不是用來補救劣質代碼的,事實上如果我們去除了代碼中的所有壞味道,當劣質代碼都被移除的時候,注釋已經變得多余,因為代碼已經講清楚了一切。?
??如果你希望徹底根除這些壞味道,這本書的第六章到第十二章提供了完整的操作手冊,趕緊讀這本書吧!
### Clean Code 《代碼整潔之道》

??其實我應該先介紹下面那本書,喜歡下面那本書的原因是書中有很多非常精煉但是有用的Tip,這些Tip可以說是大師級的經驗總結;而我個人喜歡這本書可能是因為非技術方面的原因(我喜歡這本書中的插圖)。這本書的第一章的第一句話是這樣說的:讀這本書通常有兩個原因:1. 你是一名程序員。2. 你想成為更好的程序員。我們需要更好的程序員。?
??這本書的每一章都可以總結出一句話或是一張圖,就是下面這些:

??本書的第一章是關于什么是整潔代碼的討論,引用了Bjarne Stroustrup(C++之父)、Grady Booch(UML的創始人之一)等人當然也Bob大叔(本書的作者Robert Martin)自己對整潔代碼的理解。順便說一下,上面那張圖上的代碼應該是保齡球計分程序(你必須佩服我的眼力)。

??不管是現實世界還是軟件項目中,命名都是一件讓人頭疼的事情,給小孩起過名字的就知道,你希望把你對孩子的期望包含在這個名字中,你又希望這個名字讀起來要好聽,至少不至于將來成為別人的笑柄(比如龐光大、魏升京這樣的名字),可能你還要考慮族譜的排輩等等。軟件項目中的命名情況會更加復雜,簡單的說命名的原則是“見名知意”,當然你還需要用各種方式防范命名沖突的問題,不同的編程語言也有自己不成文的像契約一樣的命名規則和方式(例如匈牙利命名法),這些可能都是需要考慮的事情。

??第三章講的是函數,說了這么一句話:Function should do one thing. They should do it well. They should do it only. (函數只應該做一件事情,把一件事情做好,而且只由它來做這一件事情),聽起來很簡單的一句話但是要踐行這條原則卻并不容易,所以我們的代碼中才會有很多的壞味道(上一本書中提到的東西)。事實上,上升一個層次,我們在設計類的時候也應該如此,這是面向對象設計原則中說的單一職責原則(SRP),當我們的代碼中出現了冗長的方法或者巨大的類的時候,我們就應該依據職責來對其進行拆分,這樣程序的結構才會趨于合理,最終達到“高內聚”的目標。當然,這一章里面還提到很多理念,包括:Command Query Separation(一個方法要么執行某種命令,要么返回查詢數據)、DRY(不要重復自己)、Prefer Exceptions to Returning Error Codes(異常優于返回錯誤碼)等。

??第四章講的是注釋,有一句話我很喜歡,說的是:Comments Do Not Make Up for Bad Code (注釋不是對劣質代碼的補救)。事實上好的代碼即便沒有注釋也擁有良好的可讀性,但恰當的注釋會讓代碼變得更可讀、可維護性更高。

??第五章講的是代碼風格。現代IDE(集成開發環境)幾乎都有代碼格式化代碼的功能,你只需要設置好你使用的代碼風格就可以了,其實不只是IDE,很多高級的文本編輯工具也能夠按照指定的風格格式化你的代碼。用什么樣的代碼風格不是關鍵,關鍵是整個項目組的成員應當使用相同的代碼風格,讓多個人編寫的代碼看起來像一個人書寫的。我個人特別鐘愛1TBS(One True Bracing Style,也叫做K&R風格,這種風格是Kernighan和Ritchie兩位老師在The C Programming Language一書中使用的代碼風格),當然Allman風格(FreeBSD系統的作者之一使用的代碼風格)也是很好的選擇。

??第六章討論的是對象和數據結構,讀完之后的感覺是雖然我們天天都嚷著吼著要面向對象編程,但是很多時候我們都使用了類的退化結構,包括我們開發時經常使用的失血模型和貧血模型(事務腳本模式)都和面向對象的設計理念相違背。我得承認在讀這一章的時候我沒有太抓住作者的觀點,也歡迎大家來幫助我理解這章的內容。

??第七章對錯誤處理(異常)的講解仍然是非常精彩的,整潔的代碼中對錯誤的處理應當是被分離的關注點(不要跟正常的業務邏輯混雜在一起),而面向對象中的異常機制就是一種在不打亂原有業務邏輯的前提下處理掉程序在運行時發生的不正常狀況的手段。這章有兩個觀點我特別欣賞,一是Use Unchecked Exceptions(非受檢異常允許你在適當的地方處理異常,而適當的地方就是異常影響代碼執行邏輯的地方,不管做哪種類型的應用,都應該盡可能向用戶隱藏異常的發生,除非發生了不可挽救的狀況,這才是符合最小驚訝原則的設計);二是Don’t Return Null(如果一個方法在出狀況的時候返回null,那么調用者都要通過頻繁的檢查返回值來判定是否出錯,一旦忘了這件事情就有可能出錯,既然null是一種異常狀況,那么用拋出異常的方式來代替null明顯是更好的做法)。

??第八章的內容對實際開發有重要的指導意義,因為我們的項目中不可避免的要使用第三方工具,因此我們需要將這些東西整潔的納入到我們的系統中,這時就需要考慮系統邊界的問題。有的時候我們會千辛萬苦的發現系統中的一些bug是來源于第三方工具的,當然我們基本上沒有時間去重頭學習和研究第三方工具或者自己寫代碼來實現第三方工具的功能,但是我們至少應該先對第三方工具進行測試。我在以前的項目中,即使用Apache提供的那些著名的第三方工具,我的做法也是先寫測試代碼對這些工具的可用性和有效性進行證實,當然有的時候可能是過于謹慎了,但這種習慣和做法本身是好的行為。在這種場景下,適配器模式是非常好的設計,它不僅能將不兼容的接口改寫成兼容的接口,還能夠對通過對第三方工具重新封裝來避免邊界的變化對系統的影響。

??第九章的內容是單元測試。Bob大叔是TDD(測試驅動開發)的倡導者,這一章講的是如何編寫整潔的測試,Bob大叔的答案是FIRST規則(Fast、Independent、Repeatable、Self-Validating、Timely)。

??第十章介紹類的設計,最重要的還是SRP。

??第十一章是關于系統設計的內容,開篇引用了微軟首席技術官Ray Ozzie的一句話:Complexity kills. It sucks the life out of developers, it makes products difficult to plan, build and test. (復雜要人命,它消磨開發者的生命,讓產品難于規劃、構建和測試)。這章對于希望了解面向切面編程的開發者是極好的,包括了對依賴注入、代理模式以及AOP的探討。

??第十二章探討了系統的迭代式演進。

??第十三章對并發編程的討論非常經常,很多開發者都畏懼并發編程,也有的開發者迷信多線程可以解決所有的并發問題,如果你是這兩類人之一,本章會教給你真正的并發編程。

??第十四章是一個精彩的案例用來講解對代碼的持續改進,你可以自己好好閱讀一次。
??第十五章到第十七章說的都是重構,相當精彩。你在《重構》中了解過的代碼的壞味道及其改進方案這里幾乎都能見到它是如何應用的。
總之,這本書從引言到附錄都無比精彩,趕緊去閱讀吧。
### The Pragmatic Programmer: From Journeyman to Master 《程序員修煉之道:從小工到專家》

??這本書最初出中文譯本的時候,它的名字叫《務實的程序員》,而這本書也正像它書名的副標題那樣,是一本帶領程序員從小工成為行業專家的著作。這本書里有70個Tip(指點、提示),這些Tip都是短小精煉的句子,但都是大師們編程經驗的總結和沉淀。因此不管什么時候看這本書,也不管你翻到第幾頁,總會發現這樣的Tip,而它們也會讓你有醍醐灌頂的感覺。下面分享了這本書部分的Tip:
- Tip8: Invest Regularly in Your Knowledge Portfolio (定期為你的知識資產投資)
- Tip9: Critically Analyze What You Read and Hear (批判的分析你讀到的和聽到的)
- Tip10: It’s Both What You Say and the Way You Say It (你說什么和你怎樣說同樣重要)
- Tip11: DRY - Don’t Repeat Yourself (不要重復自己)
- Tip13: Eliminate Effects Between Unrelated Things (消除無關事物之間的影響)
- Tip18: Estimate to Avoid Surprises (通過估計來避免意外發生)
- Tip20: Keep Knowledge in Plain Text (用純文本保存知識)
- Tip23: Always Use Source Code Control (總是使用源碼控制)
- Tip27: Don’t Assume It - Prove It (不要假定要證明)
- Tip29: Write Code That Writes Code (用代碼生成代碼)
- Tip31: Design with Contracts (按照契約設計)
- Tip33: If It Can’t Happen, Use Assertion to Ensure That It Won’t (用斷言確保不能發生的不發生)
- Tip38: Put Abstraction in Code, Details in Metadata (將抽象置于代碼,細節置于元數據)
- Tip39: Analyze Workflow to Improve Concurrency (分析工作流以改善并發性)
- Tip42: Separate Views from Models (讓視圖和模型分離)
- Tip63: Coding Ain’t Done ‘Til All the Tests Run (測試不通過編碼不停止)
- Tip69: Gently Exceed Your User’s Expectations (超出用戶期望一點點就好)
??除此之外,該書中有很多名人名言以及很多經驗的分享,例如:“不要讓調試改變了被調試系統的行為”、“異常盡量不被作為程序正常流程的一部分來使用”、“要有始有終,分配資源的程序也應當釋放它”、“最大的弱點是害怕暴露弱點”等等。 當然,這本書也包括了對契約式編程、解耦合、重構、算法效率、測試等內容的探討。?
??老實說,整本書的內容都很棒,附錄也不例外,附錄A中列出了一些作者推薦閱讀的計算機書籍,這些書籍正好也出現在了我們給的這個必讀書籍的列表中,真的是英雄所見略同(就算我臭美了一次哈)
### The Practice of Programming 《程序設計實踐》

### Design Patterns 《設計模式》

### Domain-Driven Design 《領域驅動設計》

### The Art of UNIX Programming 《UNIX編程藝術》

??這本書是給予我無數次幫助的書籍,我會慢慢的把我讀這本書的心得記錄在這里。每次當我遇到問題不知所措的時候,這本書總是能給我答案;在我參加的所有面試中,只要有答不上來的問題,想想這本書中的一些只言片語就能在電光火石間發現答案。
### Practical API Design 《軟件框架設計的藝術》

### Patterns of Enterprise Application Architecture 《企業應用架構模式》

??還有很多好書可能因為選擇標準的不同在雷達圖中雖然沒有出現,但是仍然值得每個程序員去閱讀,這些好書包括:
### The C Programming Language 《C語言程序設計》

??C語言之父Dennis Ritchie以及Brian Kernighan兩位老師合著的神一樣的書籍。我到現在都沒有想明白為什么國內只有極少數的幾所大學用這本書作為教材,難道C語言的入門書中還有出其右者嗎?這本書的內容無比精彩,不管是對于初學者還是有經驗的程序員;這本書中的代碼無與倫比,幾乎每一段代碼都是經典。即使你還沒有讀過本書,但是你一定聽說過一個叫Hello, world的程序,該程序就出現在這本書中。
### The Mythical Man-Month 《人月神話》

??這本書是號稱軟件工程領域的第一奇書,與《人件》合稱為軟件工程著作中的倚天劍和屠龍刀。Brooks博士為人們管理復雜項目提供了最具洞察力的見解。既有很多發人深省的觀點,又有大量軟件工程的實踐,其內容都是來自Brooks博士在IBM公司System/360家族和OS/360中的項目管理經驗。這本書是項目經理和系統分析師必讀的不朽之作,也是流行了30多年的傳奇經典。
### Hackers and Painters 《黑客與畫家》

??該書是我最近幾乎每天都翻翻的一本書,準確的說這本書是硅谷創業之父Paul Graham的文集,主要介紹優秀程序員(書中稱之為黑客,當然這和我們尤其是國內對黑客的理解有所差別)的愛好和動機,討論它們如何成長以及如何為世界做出貢獻,當然也包括了對編程語言和優秀程序員工作方法等的探討和思考。該書的內容不但有助于了解計算機編程的本質、互聯網行業的規則,還會幫助讀者了解我們這個時代,迫使讀者獨立思考。該書的中文版是阮一峰博士翻譯的,翻譯的水準和書中的旁注都相當好。
### The Art of Computer Programming 《計算機程序設計藝術》




### Introduction to Algorithms 《算法導論》

### Object-Oriented Analysis and Design with Applications 《面向對象分析與設計》

除此之外,因為自己做了很長時間的Java程序員,有一些Java方面的好書可以推薦給大家
### Thinking in Java 《Java編程思想》

### Effective Java

### 《Java與模式》

### The Well-Grounded Java Developer 《Java程序員修煉之道》

### POJOs in Action

??其實國產的Java書籍里面也有部分優秀的書籍,雖然國產書的質量總體偏低,但是最近幾年還是有很多有責任感的技術作家(他們很多人同時也是一線程序員或架構師)寫了不少好書。
### 《設計模式之禪》

### 《編寫高質量代碼:改善Java程序的151個建議》

### 《Spring 3.x企業應用開發實戰》

### 《Tomcat與Java Web開發技術詳解》

### 《瘋狂Java:突破程序員基本功能的16課》

??如果你以前不是計算機相關專業又想轉型從事軟件行業,那么我推薦先看一些專業氣質養成類書籍,當然最入的書就是《計算機導論》、《計算機文化》之類的書,也可以看看《計算機科學概論》或者是《計算機專業英語》,建議看原版的,一方面對整個行業有一個全面的了解,另一方面鍛煉一下自己的英語水平。無論如何,我覺得程序員還是應該讓英語成為自己的工作語言。
### Computer Concepts 《計算機文化》

### Computer Science Illuminated 《計算機科學概論》

### Computing Essentials 《計算機專業英語》

??如果你希望從零基礎開始做一個Java程序員,那么我建議的這些書的閱讀順序是這樣的(每項讀一本就OK了):
1. Computer Concepts / Computer Science Illuminated
1. The C Programming Language
1. Core Java (Vol. 1 & Vol. 2) / Introduction to Java Programming
1. MySQL Crash Course / 深入淺出MySQL / Sams Teach Yourself SQL in 10 Minutes
1. Thinking in Java / Effective Java / 編寫高質量代碼:改善Java程序的151個建議
1. Servlet & JSP: A Tutorial / Head First Servlets & JSP
1. Java與模式 / Design Patterns Explained / 設計模式之禪
1. 精通Hibernate / Java Persistence with Hibernate
1. Spring in Action / Spring企業應用開發實戰 / Spring技術內幕
1. Clean Code / Refactoring Impoving the Design of Existing Code
1. The Well-Grounded Java Developer
1. Algorithms / Data Structures and Algorithm Analysis in Java
1. POJOs in Action / Core J2EE Patterns: Best Practices and Design Strategies
1. Java Performance
1. Software Engineering A Practitioner’s Approach
說明:讀書心得我只能一點點與大家分享和交流了,爭取在一個月之內把這件事情搞定吧:)