究竟怎樣寫代碼纔算是好代碼

今天讓我們來談談代碼吧。代碼重要嗎?當然,代碼就是設計(Jack W.Reeves, 1992);代碼是最有價值的交付物。我們需要好代碼嗎?在給“好代碼”下個定義之前,這個問題無法回答。那麼,究竟什麼是好代碼?

看下面這段英文解釋:

‘Good code’ is code that works, is bug free, and is readable and maintainable. Some organizations have coding ‘standards’ that all developers are supposed to adhere to, but everyone has different ideas about what’s best, or what is too many or too few rules. There are also various theories and metrics, such as McCabe Complexity metrics. It should be kept in mind that excessive use of standards and rules can stifle productivity and creativity. ‘Peer reviews’, ‘buddy checks’ code analysis tools, etc. can be used to check for problems and enforce standards.

解釋如下:

好的代碼是代碼運行正常、bug很少、並且具有可讀性和可維護性。一些企業自己有所有開發人員都必需遵守的編碼規範,但是對於什麼樣的代碼是最好的每個人的都有自己的標準、或者有太多的或太少的編碼規則。這有多種原則和標準,例如,McCable 的複雜度度量。的確使用過多的編碼標準和規則可能降低生產率和創造性。“同行評審”或“同事檢查”代碼分析工具等,都能用來檢查問題或堅持標準。

那麼接下來我們深入介紹下,什麼是好代碼的標準呢,請看下面解釋:

一、代碼命名規範:

1、 package包名全部由小寫的ASCII字母組成,用“.”分隔。在此項目中,所有的包均以“com.abc.ticket”開頭。

2、 class 類名應當是名詞,每個內部單詞的頭一個字母大寫。應當使你的類名簡單和具有說明性。用完整的英語單詞或約定俗成的簡寫命名類名。
【示例】public class UserManager

3、 interface接口名應當是名詞,每個內部單詞的頭一個字母大寫。應當使你的接口名簡單和具有說明性。用完整的英語單詞或約定俗成的簡寫命名接口名。
【示例】interface TicketManagement

4、 Class 成員屬性及變量的命名 (*) 變量名全部由字母組成,頭一個字母小寫,以後每個內部單詞的頭一個字母大寫。變量名應該短而有意義。變量名的選擇應該易於記憶。一個字符的變量名應避免,除非用於臨時變量。通常臨時變量名的命名規則爲:i,j,k,m,n用於整數;c,d,e用於字符。

5、常量的命名,Java 裏的常量,是用static final 修飾的,應該用全大寫加下劃線命名,並且儘量指出完整含義。
【示例】static final String SMTH_BBS=”bbs.tsinghua.edu.cn”; 

6、數組的命名,數組應該總是用下面的形式來命名:byte[] buffer; 

7、方法的參數和變量的命名規範一致,且應使用有意義的參數命名,如果可能的話,使用和要賦值的字段一樣的名字。
【示例】setCounter(int size){ this.size = size; } 

8、 方法命名(*)方法的命名應當使用動詞,頭一個字母小寫,以後每個內部單詞的頭一個字母大寫。在方法名的選擇上應意義明確便於記憶。對於屬性的存取方法,應使用getXXX()和setXXX()名稱,以isXXX(),hasXXX()來命名返回值爲boolean 類型的方法。

以上幾條如果符合就算是好代碼了嗎?當然不是,這只是代碼中最基本的命名規範而已,就算不符合最多就是代碼不好看,沒什麼其他影響。

二、代碼邏輯規範

1、需求、設計中的重點功能(結合需求/設計的評審產出)

2、代碼格式校驗
action/façade等系統入口是否有數據格式校驗
需要存入數據庫的數據字段是否有長度校驗

3、分支/循環
if-else/switch是否處理了所有分支
分支的條件語句是否有“副作用”;即,條件語句是否會改變系統狀態/數據等
循環邊界是否覆蓋了所有元素
是否有死循環等

4、異常處理
是否有“吃掉異常”的情況
是否記錄了異常日誌
如果二次拋出,是否有合理的異常層次/結構
如果內部處理,對異常的處理是否能保證後續代碼正常運行

5、單元測試
是否有單元測試
單元測試是否自動化
單元測試是否能完整覆蓋需求

6、 事務處理
事務範圍是否合理;或者說,是否把不必要的操作放到了同一個事務中
事務傳播方式是否合理(required,never,new等配置)

7、sql語句
sql語句是否正確
使用mybatis的動態語句時,是否有潛在的sql語法問題

8、第三方組件
使用Redis,RabbitMQ等組件,是否真的對組件完全瞭解,在使用的過程中是否正確執行了開啓與關閉操作。

寫到這裏,可能會有不少讀者認爲,代碼規範也就這些了吧,按照上面二類寫完算是優秀的代碼了嗎?其實還是遠遠不夠。

三、可讀性,可維護性

曾經看過一段代碼,一個method幾千行代碼,所有業務邏輯都揉在了一起。然後沒有人願意再維護了,修改一點就會引發不可預知的錯誤,代碼又臭又長。在這種情況只能重構,於是我在部門內部推廣二本書《代碼整潔之道》和《重構-改善既有代碼的設計》並且制訂部門自己的開發風格,通過組織所有開發人員練習小項目的開發,使整個部門的開發風格整齊劃一,不管是老同事還是新同事,都能夠非常快速的上手,程序中依賴度降低,結構非常清晰。

四、性能瓶頸

在真實工作中,很多程序員其實在開發完程序後不去真正關注程序的性能和響應時間到底如何,憑的是以往開發經驗在開發的過程中儘可能的去減少問題點。

這樣就只能在生產環境中去驗證性能問題了,實際這種做法風險較大,所帶來的損失也是較大的,我們在開發完程序後,不僅要採用Junit或者JMock這樣的工具進行業務功能自測,更重要是能夠採用相應的工具和命令進行代碼性能和響應時間的測試,在第一關就能夠找出可能出現的一部分問題點,那麼經常使用的工具和命令如下:
top,vmstat,pidstat,Hprof,Btrace,Dtrace等命令。

具體可以參考我以前寫過的文章二篇:
http://blog.csdn.net/u013970991/article/details/52035153
http://blog.csdn.net/u013970991/article/details/52035133

五、代碼容錯

  • 曾經有一個案例:
    X同事在“統一配置管理系統“中將一個參數配置在裏面,當參數進行修改的時候相應的程序會馬上做出改變進行相應邏輯調整,可是另一個A同事在操作這個系統的時候配錯了參數,這時候系統在生產環境中就開始報錯,以致於應用程序崩潰,邏輯無法進行下去造成較嚴重的生產事故,最後恢復完參數故障時間已經進行了十幾分鍾。針對這個問題當時產生了爭論,到底是配置人員的錯,還是開發人員的錯。

其實在我看來,到底是誰的問題暫且放在一邊,關鍵是開發人員是否在寫程序的過程中有沒有多一絲的思考,多考慮一些問題點,程序員要時刻懷着一顆懷疑的心和敬畏的心對待自己寫的程序,像上面的問題我們完全可以做一些異常捕獲和默認設置,在出錯的時候至少能夠讓應用程序跑下去而不能整體報錯,讓用戶無法繼續使用。

  • 再說一個案例:
    某部門在開發“統一配置管理系統”,使用的是Zookeeper組件,而且它的工作原理是當某節點改變的時候,主動去通知所註冊的系統,但是有個前提是如果那些系統,有一部分沒有得到通知,有一部分得到了通知該怎麼辦,比如某幾個系統在通知的時候正好在重啓,這時候zookeeper就不能通知到相應的系統,於是在使用該“統一配置管理系統”的時候,出了生產事故。

其實還應該再重複說一下,程序員應該持有懷疑的精神面對調用的系統和被調用的系統,不要把穩定、安全、可靠寄託於別人身上。

究竟怎樣寫代碼才能算好代碼?這是一個有爭議的話題,每個人的理解可能都不同,關鍵是通過討論這個話題制訂一個符合自己部門要求的規範,這樣有依據的代碼纔可能成爲好的代碼。

(function () { ('pre.prettyprint code').each(function () { var lines = (this).text().split(\n).length;var numbering = $('
    ').addClass('pre-numbering').hide(); (this).addClass(hasnumbering).parent().append( numbering); for (i = 1; i
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章