關于代碼質量的一些思考
關于代碼質量的一些思考
今天剛好看到同事寫一段代碼,跟同事聊到一個代碼風格的問題,討論了一會,也沒得出什么結果。回來想了想,之所以大家觀點不一樣,其實是一開始代碼追求的目的就不一樣。
1. 可讀性</h2>
1. 可讀性</h2>
我是一直認為代碼的可讀性是最重要的目標。太多的書都講到一個觀點:“代碼是寫給人閱讀的,只不過剛好能被計算機執行”。
大部分做自己產品的團隊,一個項目的維護時間可能是開發時間的5倍以上,而維護的常見內容都是一些小功能以及已有bug的修復。可讀性帶來的好處就 是,非常容易弄清一段功能邏輯,從而定位問題。遇到團隊人員變動,新人也能很快的熟悉。我在公司換過很多組,也接手過很多的項目(大多數的可讀性并不 好),就這一點來說,真是切膚之痛。
什么樣的代碼,算是可讀性好?我跟別人提過一個標準:“你寫的代碼,過了幾個月、半年、一年,跟你說道一個功能,即使你不記得這個功能怎么做,你也能說清楚這個功能寫在哪個地方”。這個標準我自己認為還是很有效的。
那用什么方法可以增加可讀性呢?合理的拆分和抽象會增加可讀性。另外,我其實一直崇尚“用最常用的方法寫程序,直到它發展到你已經理解困難的時候,再去重構”。
2. 代碼美學與合理性</h2>
2. 代碼美學與合理性</h2>
經歷過跟很多人的合作,我發現,很多非常優秀的開發者,會從直覺上把一個代碼片段“是否優美”作為第一考慮的目標。他們會追求一些高級編程技巧的合 理運用,或者開發一些公共組件,來達到行數足夠少,或是表達足夠清晰的目標。這個好像教材里也不曾提到的,我把它叫做“合理的代碼美學”。
對于Java代碼來說,有人就喜歡把一些常見功能,用自定義注解,然后用AOP來完成注解的解釋。例如,一個功能需要隨時可以打開或關閉,我可以通過一個注解來完成它而不是在業務處理中寫一些if-else-check。
<pre>@NewFeatureEnabled public void doSomething(){ }</pre>實際上,完成一個“優美的”小功能,也就是用自己心中認為最好的方法去完成一件事,這樣的滿足感,也是讓人持續編程的動力。嚴格的說,這樣的代碼有 沒有給代碼質量帶來提升呢?肯定有。第一很多時候這樣的代碼會經過更多的考慮,必然有更高的質量;第二很多更好的開發技巧,都是來自這些“不一樣”的追 求。
但是我認為,軟件開發與藝術最大的不同是,它是一個多人合作勞動,一個人覺得合理的,其他人未必會感同身受,甚至會恰恰相反。這樣的代碼是蛋糕上華 麗的三層奶油,有時會給人眼前一亮的感覺,但是也可能會讓人找不到蛋糕本身。所以我的建議是:“如果你要用一個新技巧,最好積極宣傳,和團隊達成共識”。
比如這個@NewFeatureEnabled的功能,我會想:“如果別人接手這個項目,他是不是知道 NewFeatureEnabled是什么意思?即使知道,他怎么知道這個功能的開關,是由其他地方一個AOP來完成的呢?”但是如果大家都接受這個方 式,知道AOP是在哪里配置,如何工作的,那么也就是一個還不錯的嘗試了。
3. 可復用性</h2>
3. 可復用性</h2>
追求復用性是開發者的一個本能。大家都希望少寫代碼,最好要用的時候,一切都準備好了。我見過太多的代碼為了復用而設計,但是基本上所有以復用為第一目標的代碼,都沒有什么好質量。不是說可復用性不重要,而是它容易讓人走上歪路。
比較好的復用方式,應該是零件式的復用,每一塊都有各自的規范和存在,但是這樣的復用是一個嚴肅的過程,往往也達不到最大化的“代碼復用”。為了復 用的抽象,常見的就是把一段公用的代碼塊獨立出來成為函數或者類,而這部分的邏輯甚至都是無法獨立存在,也單獨無法被人理解的。這種拼接式的復用,類似于 為了表示一只貓和一只狗,把貓的身體和狗的身體復用成一塊,然后寫一堆判斷代碼來告訴別人什么時候這個身體是貓,什么時候這個身體是狗,最后再跟各自的腦 袋組合起來。當然了,沒有人知道這個“既是貓又是狗的身體”是什么。如果你想知道貓長什么樣,估計得先給它做個縫合手術才行。
如果一個項目以這樣的思路開發久了,你會發現代碼邏輯散落在各處,各種業務場景互相交織,任何改動都會牽一發動全身。
如果要為可讀性排個名的話,我認為大概是:
毫無頭緒的抽象<只為復用的抽象<不做抽象<簡單的抽象<局部優美的代碼<整體優美的代碼<清晰的層次結構并抽象<整體優美并且被大家接受的代碼
最后一個層級,這樣的代碼實際上已經是更高的生產力了,就像Spring之于滿地new對象就是個進步。可能代碼進化到最后,真的就是跟自然語言那么簡單,到時候我們就需要研究怎么在代碼里寫詩了!
來自:http://my.oschina.net/flashsword/blog/389251