如何提升代碼可讀性?其實不是你想的那樣
作為開發者,可能會經常聽到“代碼首先是寫給人看的”、“寫可讀的代碼相當重要”等等。
對于如何使代碼的可讀性更強,開發者往往都有自己的看法。那么你可曾仔細想過什么才能真正使代碼可讀性增強。
一些標準答案
無論你使用什么編程語言,你都可能會認同下面的建議可以增強代碼的可讀性:
- 好的變量、方法、類名
- 一個變量、類、方法只做一件事
- 一致的縮進,一致的格式
- 減少代碼中的嵌套級別 </ul>
當然,還有很多其他標準答案,比如 Clean Code(Robert Martin 著)和 Code Complete(Steve McConnell 著)兩本書中說的,你應該讀一讀。
或許你要說,這些東西我都知道。那么,下面就是一些你可能沒有考慮的、關于代碼可讀性的更深層次的東西。
讀者的經驗
給我一段代碼,我能在 2 秒內告訴你這段代碼是否寫得好,是否具有很強的可讀性(至少我會告訴你我的意見)。
同時,如果我將我寫得最好的、可讀性很高的代碼給一個編程新手,他們可能也不會發現這些代碼與其他代碼有什么不同。
雖然我的代碼中有很好的、描述性的變量名,短的命名方法和少量的參數,并且它們只做一件事,各個功能結構清晰地組合在一起,但是這些新手并沒有發現我的代碼比其他沒有考慮結構的代碼好讀到哪去。
事實上,我經常聽到其他人抱怨我的代碼中有太多的方法,難以理解,并且變量名稱太長,容易混淆。
有經驗的開發者與新手讀代碼的方式有根本的區別
一個有經驗的開發者在閱讀代碼時不會注重編程語言本身的詞匯,而會更專注于代碼實際上表達的意思——代碼的目的是什么,而不是它是如何做的。
而經驗不足的開發者在讀取代碼時,會試圖了解代碼的實際結構,初學者則更側重于實際的語言詞匯,即代碼中的編程語言試圖傳達的東西。
對他們來說,一個長變量名稱不具備描述性,而且會令人迷惑,因為這些變量名會隱藏一些事實,比如 NumberOfCoins 字面上來看表示一個整型值,而實際上它不僅僅是一個整型值。他們寧愿看到名為X或編號的變量值。
而一個經驗豐富的開發者,不會去關心整數、字符串和其他類型的變量,他們只想知道變量在系統、方法的邏輯上下文中表示什么,而不是變量的類型以及如何工作。
學習閱讀
學習閱讀代碼就像是小孩子在學習閱讀文章一樣。他們在學習閱讀時,不會去注意語法和文章傳達的思想,而只會關注詞語本身的結構。
又比如,一個經驗豐富的音樂家可以很輕松地看懂樂譜,而初學者往往需要根據樂譜來找鋼琴上對應的琴鍵或吉他上對應的品數。
可讀性約束因素
你在表達你的想法和意見時,有可能會局限于你本身所掌握的詞匯量和閱讀量,同樣,你代碼的可讀性也有可能局限于你所使用的編程語言以及編程語境。
來看個例子,下面的匯編代碼會在 DOS 屏幕中輸出“Hello World!”:
.model small .stack 100h .data msg db 'Hello world!$' .code start: mov ah, 09h ; Display the message lea dx, msg int 21h mov ax, 4C00h ; Terminate the executable int 21h end start
語言本身的復雜性,導致編寫的代碼難以閱讀。無論你是個多么優秀的程序員,這種代碼的可讀性對你來說總會有上限的。
現在再來看看 C# 中的 Hello World:
public class Hello1 { public static void Main () { System.Console.WriteLine ("Hello, World!"); } }
下面是 Ruby 的:
puts "Hello, world"
你知道 Ruby 為什么如此流行了吧!如果你了解 Ruby 語言中大量的詞匯和語法結構,你會發現你可以很清楚地表達一個事物。
我想說的是,你擁有的詞匯量越大,你表達的方式就會越簡潔,可讀性就越高,當然,這是對于那些同樣擁有高詞匯量的讀者來說的。
我們可以得出什么?
從上面的內容中可以得出,我們的詞匯量和經驗會影響代碼的可讀性。我們還需要去考慮誰將閱讀我們的代碼,他們的詞匯量和經驗如何。
在 C# 中,通常會爭論是否該使用條件運算符,比如我們應該寫這樣的代碼:
var nextAction = dogIsHungry ? Actions.Feed : Actions.Walk;
還是這樣的
var nextAction = Actions.Noneif(dogIsHungry) { nextAction = Actions.Feed }else { nextAction = Actions.Walk; }
我以前會說第 2 種方式更好,但我發現我經常會寫第 1 種。現在如果有人問我哪種好,我會告訴他“視情況而定”。我的意思是,你需要看讀你代碼的人是否了解條件運算符。
編程語言也如同普通語言學習,比如英語,有人認為英語中有大量的詞匯和荒謬的語法,應該減少一些,這樣學習起來會更容易。但是,如果這樣,就難以簡潔地傳達信息了。
那么你認為,在開發中,應該有一種復雜的編程語言來增強開發者的表達能力,增強代碼的簡潔性和可讀性(當然,這需要足夠多的學習成本),還是應該保持簡單的編程語言,來寫復雜的、較長的代碼呢?