編寫好代碼的10條戒律
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. 對代碼進行復查
我們都會犯錯誤,沒有什么能比請別人對我們代碼做一個非正式快速復查更好的辦法來查找錯誤了。最好不要等到代碼都完成以后再復查,當某些重要部分的代碼完成后,或者離上一次復查相隔幾天之后,就進行復查。