文章目錄
- 第七章 錯誤處理
- 第八章 邊界
- 第九章 單元測試
- 第十章 類
- 第十一章 系統
- 第十二章 迭進
全書一共400多頁,一共17章,第十三章講並發,並且在附錄A中有對並發的補充,第十四到十六章是一些Java代碼的案例,第十七章相當於一個總結。本次寫讀書筆記主要涵蓋前十二章的內容,由於篇幅分為上下兩篇。本篇為下,個別章節因為能力有限,沒有完全弄懂,就先空著了。
第七章 錯誤處理
錯誤處理簡單來說就是當軟體出現錯誤時還能正常工作。錯誤處理很重要,但不能打亂的原本的代碼邏輯。 使用異常處理而非返回碼,底層往上拋,最上層集中處理。這點在第三章函數中也提到過,之所以看到有的地方是使用錯誤返回碼,是因為早期的一些語言沒有異常處理機制。現在的語言基本都有異常處理機制。 異常的資訊應該足夠充分(包含出錯的位置以及原因)。 不要在catch塊中去實現商務邏輯,就是說當出現異常的時候一定要拋出,而不要改變狀態或是做其他一些操作,這樣會留下很多陷進。 底層的方法不要返回Null值,否則在調用時會添加很多的判斷,可以拋出異常或返回特例對象,特例對象是指返回一個函數傳回值類型的Null 物件。 不要傳遞Null值。
第八章 邊界
無
第九章 單元測試
我工作以來所經曆的公司中都很少使用單元測試,以致於我現在對單元測試這方面還不是特別熟悉,只是在自己的個人項目中寫過一些單元測試的代碼。在DotNet平台下可以使用VS內建的單元測試功能或是NUnit。 現在有一種編程的方法叫TDD(測試驅動開發),意思是先寫單元測試,然後寫對應的代碼,通過修改調試讓寫的代碼通過單元測試。使用TDD,會使測試覆蓋所有的代碼,測試代碼和生產代碼的比例有可能會達到1:1 ,所以也會帶來成本的問題。TDD三定律:
- 在編寫不能通過的單元測試前,不可以編寫生產代碼;
- 只有編寫剛好無法通過的單元測試,不能編譯也算不通過;
- 只可編寫剛好足以通過當前失敗測試的生產代碼。
測試代碼和生產代碼一樣的重要,也需要保持整潔。測試代碼要隨著生產代碼的修改而修改,否則只會產生大量無用的測試代碼,而且也會給生產代碼的修改帶來風險。 單元測試的好處:
- 有了測試不用擔心對代碼的修改;
- 有了測試可以毫無顧慮的去改進架構和設計;
整潔測試的三要素 :可讀性、可讀性、可讀性,測試中的可讀性甚至比產生代碼中的可讀性還要重要。要做到高可讀性,測試代碼需要滿足:明確、簡潔和足夠的表達力。 每個測試都可以拆分為三個環節:構造測試資料、操作測試資料、檢驗操作是否達到預期結果。 雙重標準:指的是在測試環境中和生產環境中有些條件不必完全一致。生產環境中有時要考慮記憶體、cpu等效能問題,而在測試環境中不必做這些限制。 每個測試一個斷言,不必完全糾結,但單個測試斷言數應該最小化。 每個測試函數只測試一個概念,還是單一職責的問題。 整潔的測試代碼要滿足“FIRST”原則
- 快速(Fast):測試回合應該夠快,如果運行很慢就不會想頻繁去運行它,就會導致不能及時發現問題。
- 獨立(Independent):測試應相互獨立,某個測試不應成為下個測試的設定條件,應該可以單獨運行每個測試。測試如果相互依賴,會導致一連串的測試失敗,尋找問題比較困難。
- 可重複(Repeatable):可以在任何環境中重複通過。
- 自足驗證(Self-Validating):測試應該有布爾值輸出,無論是成功還是失敗。
- 及時(Timely)測試應及時編寫,單元測試應該在使其通過的生產代碼編寫之前編寫。按這種要求及時TDD開發了,但在實際工作中並不是總能遇到TDD開發的團隊。
第十章 類
類通常由變數、屬性和方法組成。按照書中所講的Java的約定,類應該由一組變數開始,如果有靜態公用常量,應該放在前面,然後是私人靜態變數和私人實體變數。公用函數跟在變數之後,一些供公用函數調用的私人工具函數在公用函數之後。 和函數一樣,類也應該要儘可能的短小。但和函數不同不是以程式碼數來權衡,而是以職責。如果無法準確的為某個類命名,則有可能是該類的職責過多。 單一職責原則(SRP):類或模組應該有且只有一條加以修改的理由。 在實際的工作中很多開發人員往往不會思考這麼多,他們只想著讓代碼可以工作就可以了,所以經常出現幾千行的大類。系統應該是有許多短小的類而不是少量巨大的類組成。每個小類有單一的職責,只有一個修改的原因,所有這些小類在一起協同工作完成系統的功能。 高內聚:如果一個類中每個變數都被每個方法所使用,則該類有最大的內聚性。 保持內聚性得到許多短小的類。 上面說到每個類應該有單一職責,就是說類之間應該低耦合,但類的內部應該是高內聚的。如果一個類中的每個變數被每個類使用,則該類具有最大的內聚性。內聚性高說明變數和方法相互關聯形成一個邏輯整體。 重構函數也會促使類職責的分離,看下面情境: 將一個有許多變數的大函數拆分成小函數,如果拆出來的代碼使用了其中4個變數,那麼就會將這4個變數作為參數傳入到小函數中,如果使用的變數越多,就意味著小函數的參數越多,這時可以講這4個變數升級成實體變數,小函數就不需要參數了,可以直接使用這些變數。這樣就使內聚性變低,因為類中有很多的變數只為少數的函數服務,這時就可以將這些變數和函數拆分出來,單獨成類。 開放閉合原則(OCP) 依賴倒置原則(DIP)
第十一章 系統
這一章主要講的是怎樣在較高的層級--系統層級來保持整潔。 將系統構造和使用分開:軟體系統應該將啟始過程和啟始過程之後的運行時邏輯分離開,在啟動過程中構建應用對象,也會存在相互纏結的依賴關係。 本章提到的一些技術概念,下面提供一些參考學習連結:
原廠模式 http://www.cnblogs.com/oec2003/archive/2009/11/21/1607308.html
依賴注入(DI) 控制反轉(IOC) http://www.cnblogs.com/leoo2sk/archive/2009/06/17/1504693.html
擴容:不可能一開始就把系統做對,實現好當前客戶的需求,然後重構,擴容來實現新的客戶需求。 軟體系統與物理系統可以類比。他們的架構都可以遞增式增長,只要我們持續將關注面恰當的切分。
AOP http://www.cnblogs.com/zhugenqiang/archive/2008/07/27/1252761.html
第十二章 迭進
Kent Beck關於簡單設計的四條規則 1 運行所有測試
- 不可測試的系統是不可驗證的,不可驗證就不應該部署;
- 只要系統是可測試的,就會導向保持類的短小和單一的職責;
- 緊耦合的代碼是難以編寫測試的,所以編寫測試越多,就會導致使用依賴注入、面向介面編程等來使代碼解耦。
2 不可重複 3 表達程式員的意圖
- 選好的變數名、函數名和類名;
- 要記住,下一個閱讀你代碼的很可能就是你自己;
- 添加適當的注釋。
4 儘可能減少類和方法的數量 重構
- 上面的2-4點都可以通過重構的方法來達到;
- 重構的目的:提升內聚、降低耦合、切分關注面(AOP)、模組化系統性關注面、縮小函數和類的尺寸、選取好的名稱等;
- 好的函數、好的類、好的系統是重構出來的,沒有人能一開始就把事情做對;
- 重構應該要及時,發現了壞味道要及時重構,當然這個需要測試來做保障。