0. DRY: 不要重複你自己(Don’t repeat yourself)
DRY是一條最容易理解但又是相對比較難以應用的原則。它是指當你在兩處或者更多的地方發現相似代碼時,我們應當把它們抽象成一個新的函數,在之前重複的地方調用新的函數並帶上適當的參數。
DRY也許是最普遍的一條編程原則,我從未發現一個開發人員認為編寫重複的代碼是件好事。但是我發現一些開發人員在編寫單元測試時忘記了這條原則,例如:設想一下你改變了一個類的介面,之前已經為這個類編寫了很多的單元測試,如果你沒有應用DRY原則,這時你需要手動去修改所有使用這個類介面的調用,來與每一個測試執行個體的新簽名匹配。
1. 編寫短小的函數/方法
有三個非常好的理由,選擇編寫短小的函數。
- 1. 代碼會更容易閱讀。
- 2. 代碼會更容易重用(短小的函數更容易產生松耦合)。
- 3. 代碼會更易於測試。
編者註:松耦合:在軟體領域中,“耦合”一般指軟體組件之間的依賴程度。耦合度松的軟體會有較好的擴充性。
2. 給類、函數和變數使用好的命名
直接使用其他開發人員的代碼而不需要閱讀說明文檔,沒有什麼比這更好的事情了,因為代碼中的類名、函數名已經能夠告訴我們所有需要的資訊。所以,採用這種方法,每次在為你的代碼中任何元素進行命名的之前請花上幾秒鐘(思考),這會讓大家的生活變得更輕鬆。
3. 為每個類分配正確的職責
一個類只承擔一個職責(單一權責),聽起來和有些人知道的SOLID原則很相似,但是這裡不是指任意的職責,而是正確的職責。所以,如果我們要設計一個顧客類,我們不會給它建立一個銷售的行為,我們只會讓它處理所有與一個客戶相關的資料。
編者註:SOLID:物件導向設計的五項原則(是SRP單一職責原則、OCP開閉原則、LSP李式代換原則、ISP依賴反轉原則和 DIP介面分離原則,首字元的縮寫)。
4. 保持代碼的條理性
代碼條理性分兩個層次
- 物理上的條理性:無論你採用了哪種結構,包、命名空間、檔案夾等等,用一種更容易並且憑直覺就能找到代碼存放在哪裡的方式來組織你編寫的類。
- 邏輯上的條理性:不論邏輯上從屬關係如何,(只要有邏輯從屬關係)類都應該能夠互相訪問彼此的成員變數,但是如果從屬於不同的邏輯結構就應當只能通過介面來訪問。這種邏輯分組通常會被實現成(邏輯)層、服務等。
5. 編寫很多的單元測試
測試越多越好,它們是所有代碼變動的安全保證,我們會在將來的某一天需要運行這些測試代碼。
6. 儘早且經常地重構代碼(Refactor often and sooner)
軟體開發是一個持續發現的過程,為了編寫保持與新增/改變的需求匹配的高品質代碼,隨著開發的進行,重構代碼是必不可少的。由於重構是一項帶有風險的任務,需要有兩個主要的前提條件,來避免由於重構給系統引入新的錯誤。
- 1. 編寫很多的單元測試
- 2. 每一次重構的幅度要比較小。在開發軟體過程中,開始重構2000行代碼,3個小時以後發現所有的代碼都不能工作,並且導致問題的原因無從尋找,因此需要恢複到最初版本,幾乎沒什麼事能比這更讓人抓狂了。
7. 注釋是惡魔
這條特殊戒律有一點爭議,我們大多數人學到的是“注釋是一個好的習慣”,並且在一段晦澀的代碼中有一段注釋會比僅僅只有代碼好的多,這裡我的觀點是:給晦澀的代碼加註釋還不如僅僅留下代碼,只需要重構這段代碼直到它變得可讀為止。(編註:當然了,除了作者說的這種類型的代碼,在其他情況下,還是得添加必要的注釋,這不僅方便自己日後查看,更有利於後來者維護,請參閱《提高代碼可讀性的10個注釋技巧 》一文。
8. 要面向介面編程,不要面向實現編程(Code to an interface, not to an implementation)
這是一條經典的原則,面向介面編程會讓我們從實現的細節中解放出來,我們只要定義一個協議,並且依據協議調用定義的操作,期望(對方,即被調用的代碼)能把實際的實現或者運行時態的實現傳遞給我們的代碼。
9. 對代碼進行複查
我們都會犯錯誤,沒有什麼能比請別人對我們代碼做一個非正式快速複查更好的辦法來尋找錯誤了。最好不要等到代碼都完成以後再複查,當某些重要部分的程式碼完成後,或者離上一次複查相隔幾天之後,就進行複查。