最近一直擔憂Dubbo分佈式服務框架後續若是維護人員增多或變動,會出現質量的降低,
我在想,有沒有什麼是須要你們共同遵照的,
根據平時寫代碼時的一習慣,總結了一下在寫代碼過程當中,尤爲是框架代碼,要時刻牢記的細節,
可能下面要講的這些,你們都會以爲很簡單,很基礎,但要作到時刻牢記,
在每一行代碼中都考慮這些因素,是須要很大耐心的,
你們常常說,魔鬼在細節中,確實如此。
1. 防止空指針和下標越界
這是我最不喜歡看到的異常,尤爲在覈心框架中,我更願看到信息詳細的參數不合法異常,
這也是一個健狀的程序開發人員,在寫每一行代碼都應在潛意識中防止的異常,
基本上要能確保一次寫完的代碼,在不測試的狀況,都不會出現這兩個異常纔算合格。
2. 保證線程安全性和可見性
對於框架的開發人員,對線程安全性和可見性的深刻理解是最基本的要求,
須要開發人員,在寫每一行代碼時都應在潛意識中確保其正確性,
由於這種代碼,在小併發下作功能測試時,會顯得很正常,
但在高併發下就會出現莫明其妙的問題,並且場景很難重現,極難排查。
3. 儘早失敗和前置斷言
儘早失敗也應該成爲潛意識,在有傳入參數和狀態變化時,均在入口處所有斷言,
一個不合法的值和狀態,在第一時間就應報錯,而不是等到要用時才報錯,
由於等到要用時,可能前面已經修改其它相關狀態,而在程序中不多有人去處理回滾邏輯,
這樣報錯後,其實內部狀態可能已經混亂,極易在一個隱蔽分支上引起程序不可恢復。
4. 分離可靠操做和不可靠操做
這裏的可靠是狹義的指是否會拋出異常或引發狀態不一致,
好比,寫入一個線程安全的Map,能夠認爲是可靠的,
而寫入數據庫等,能夠認爲是不可靠的,
開發人員必須在寫每一行代碼時,都注意它的可靠性與否,
在代碼中儘可能劃分開,並對失敗作異常處理,
併爲容錯,自我保護,自動恢復或切換等補償邏輯提供清晰的切入點,
保證後續增長的代碼不至於放錯位置,而致使原先的容錯處理陷入混亂。
5. 異常防護,但不忽略異常
這裏講的異常防護,指的是對非必須途徑上的代碼進行最大限度的容忍,
包括程序上的BUG,好比:獲取程序的版本號,會經過掃描Manifest和jar包名稱抓取版本號,
這個邏輯是輔助性的,但代碼卻很多,初步測試也沒啥問題,
但應該在整個getVersion()中加上一個全函數的try-catch打印錯誤日誌,並返回基本版本,
由於getVersion()可能存在未知特定場景異常,或被其餘的開發人員誤修改邏輯(但通常人員不會去掉try-catch),
而若是它拋出異常會致使主流程異常,這是咱們不但願看到的,
但這裏要控制個度,不要隨意try-catch,更不要無聲無息的吃掉異常。
6. 縮小可變域和儘可能final
若是一個類能夠成爲不變類(Immutable Class),就優先將它設計成不變類,
不變類有自然的併發共享優點,減小同步或複製,並且能夠有效幫忙分析線程安全的範圍,
就算是可變類,對於從構造函數傳入的引用,在類中持有時,最好將字段final,以避免被中途誤修改引用,
不要覺得這個字段是私有的,這個類的代碼都是我本身寫的,不會出現對這個字段的從新賦值,
要考慮的一個因素是,這個代碼可能被其餘人修改,他不知道你的這個弱約定,final就是一個不變契約。
7. 下降修改時的誤解性,不埋雷
前面不停的提到代碼被其餘人修改,這也開發人員要隨時緊記的,
這個其餘人包括將來的本身,你要總想着這個代碼可能會有人去改它,
我應該給修改的人一點什麼提示,讓他知道我如今的設計意圖,
而不要在程序裏面加潛規則,或埋一些容易忽視的雷,
好比:你用null表示不可用,size等於0表示黑名單,
這就是一個雷,下一個修改者,包括你本身,都不會記得有這樣的約定,
可能後面爲了改某個其它BUG,不當心改到了這裏,直接引爆故障。
對於這個例子,一個原則就是永遠不要區分null引用和empty值。
8. 提升代碼的可測性 這裏的可測性主要指Mock的容易程度,和測試的隔離性, 至於測試的自動性,可重複性,非偶然性,無序性,完備性(全覆蓋),輕量性(可快速執行), 通常開發人員,加上JUnit等工具的輔助基本都能作到,也能理解它的好處,只是工做量問題, 這裏要特別強調的是測試用例的單一性(只測目標類自己)和隔離性(不傳染失敗), 如今的測試代碼,過於強調完備性,大量重複交叉測試, 看起來沒啥壞處,但測試代碼越多,維護代價越高, 常常出現的問題是,修改一行代碼或加一個判斷條件,引發100多個測試用例不經過, 時間一緊,誰有這個閒功夫去改這麼多形態萬千的測試用例? 長此以往,這個測試代碼就已經不能真實反應代碼如今的情況,不少時候會被迫繞過, 最好的狀況是,修改一行代碼,有且只有一行測試代碼不經過, 若是修改了代碼而測試用例還能經過,那也不行,表示測試沒有覆蓋到, 另外,可Mock性是隔離的基礎,把間接依賴的邏輯屏蔽掉, 可Mock性的一個最大的殺手就是靜態方法,儘可能少用。