登入  |  English
感謝您對「自由軟體鑄造場」的支持與愛護,十多年來「自由軟體鑄造場」受中央研究院支持,並在資訊科學研究所以及資訊科技創新研究中心執行,現已完成階段性的任務。 原網站預計持續維運至 2021年底,網站內容基本上不會再更動。本網站由 Denny Huang 備份封存。
也紀念我們永遠的朋友 李士傑先生(Shih-Chieh Ilya Li)。
自由專欄 如何寫出易懂的程式碼:跟你想的不一樣

如何寫出易懂的程式碼:跟你想的不一樣

或許你常聽到寫出易懂程式碼的重要性。開發者對於如何撰寫淺顯易懂的程式碼都很有想法,尤其越資深的開發者,意見越多。不過,你真的曾經停下敲鍵盤的手,想過如何真的撰寫易懂的程式碼嗎?


標準答案是


你或許會同意,不論使用的程式語言為何,下列項目有助於程式碼的易讀性:

  1. 好的變數、方法、類別名稱
  2. 變數、類別與方法都擁有單一目的
  3. 一致性的縮排和格式樣式
  4. 減少程式碼的巢狀層級

除此之外還有很多關於程式碼易讀性的標準答案與普遍公認的做法,我對這些沒什麼反對意見。

不過我倒是希望你對可讀性有更深入的瞭解。


詞彙和讀者經驗


我可以在看到一份程式碼的兩秒鐘裡,告訴你它寫得好不好以及容易理解與否。同時,我可以拿我寫得最好、有高度易讀性的程式碼範例,給一位新手程式設計者看,讓他們看不出,與他們看過的其他程式碼之間有何不同。

而對他們而言,與他們看過的其他程式碼相較,他們看不出兩者有何不同。

儘管我的程式碼中變數名稱具備高度描述性,僅有少量參數且名稱簡短的方法,一次只做一件事,程式碼清楚地依照功能加以組織分段。但是這些新手們一點也不覺得這樣做,比起他們未經任何結構思考的程式,有任何易於閱讀的地方。

事實上,我經常聽到有關的抱怨,抱怨我的程式碼方法太多,難以閱讀,變數名稱太長,容易讓人混淆。

這一切基本上都源自於老手與新手閱讀程式碼方式的不同

有經驗的開發者閱讀程式碼時,不會留意程式語言本身的詞彙,而是專注在程式碼表達的概念上,是程式碼的目的,而非如何步驟過程。

新手與經驗較少的開發者完全不一樣。當經驗較少的開發者閱讀程式碼時,會試著去了解程式碼的結構。新手則是把大部份重心放在語言的詞彙,而非語言試著要傳達的東西。

對他們而言,像 NumberOfCoins 這樣的長變數名稱毫無描述性,該變數的人格化表示加上過長的名稱,只會誤導他們,以為該變數除了表示一個整數之外,還包含了別的東西。他們寧願看到像 X 或 Number 這樣的變數名,因為光記住整數代表什麼就夠他們受的了。

有經驗的開發者完全不管整數或字串什麼的。他們希望瞭解的是,變數在方法或系統的邏輯語境下,所代表的意義,而非變數形態或變數如何運作。


例子:學習閱讀


想想看閱讀是如何學會的。

當孩童學習閱讀時,一開始會學習字母的發音。當小孩子第一次閱讀書本時,他們會唸出每個字。他們不會關心文法或文字要傳達的意思,他們只是將焦點放在文字本身的結構。

想像如果這篇部落格是寫給閱讀初學者看,然後受限於像童書一樣的詞彙與句子結構,那時你還會覺得這文章好讀嗎?可能不會。

同樣的情況也發生在有經驗的音樂家身上。他們能輕易閱讀樂譜,相較之下,新手則更偏好符號譜。比起那種描述該按哪個鋼琴鍵或彈哪條吉他弦的音樂說明,有經驗的音樂家覺得樂譜更容易閱讀與理解。


可讀性的限制


就像你只能用初學閱讀書籍的詞彙與結構,來表達思想時受到的限制一樣,你也會以同樣方式,受到程式語言的限制。

這最好用一個例子說明,讓我們看底下的組合語言:

.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

以上的組合語言程式碼會在 DOS 下在螢幕上印出 "Hello World"。x86 組合語言的詞彙與文法受到相當多限制,很難輕易表示複雜又可讀的程式碼。不論你是多麼棒的程式設計者,x86 組語的可讀性仍有其上限。

我們看 C# 的例子。

public class Hello1
{
   public static void Main()
   {
      System.Console.WriteLine("Hello, World!");
   }
}

關鍵在於 C# 擁有更為豐富的詞彙和更複雜的語法,足以提供用更為簡潔和易讀的方式,表達更複雜的想法。

想知道 Ruby 為何一下子這麼流行?以下是 Ruby 版的 Hello World:

puts "Hello, world"

就這麼簡單。


我並不是 Ruby 的超級愛用者,不過如果你知道 Ruby 語言的豐富詞彙和語法結構,你會發現,你可以用該語言清晰地表達你的想法。

不過我發現這樣的比較並不公平。而且 Hello World 也不是程式語言詞彙或語法的好示範。

我想說的是,你可用的詞彙越豐富,想法就可以表現得越簡潔,於是更有易讀性。不過前提是你已經掌握了這些詞彙與語法。


那麼,結論是什麼?


好了,你或許在想,這聽起挺有趣,雖然我不確定是不是完全同意,但我有點瞭解你的意思,但這又怎麼樣呢?

好問題。

從了解詞彙與經驗如何影響可讀性,我們可以得到不少好處。

首先,我們可以針對觀眾撰寫程式。

我們必須思考誰會讀我們的程式,他們的詞彙與經驗層級為何。在 C# 中,經常受到爭論的是條件運算符的使用。

我們應該把程式寫成:

var nextAction = dogIsHungry ? Actions.Feed : Actions.Walk;

或是:

var nextAction = Actions.None
if(dogIsHungry)
{
   nextAction = Actions.Feed
}
else
{
   nextAction = Actions.Walk;
}

一直以來我都站在支持第二種寫法的陣營這邊,不過現在我發現,我常常寫的是第一種。如果你問我哪種比較好,我的答案是看情況。理由是,假如你的觀眾不知道條件運算符,這種寫法可能會讓他們感到迷惑。不過如果你的觀眾熟悉條件運算符,那麼使用 if 語句的冗長版本就顯得浪費空間。

從這項觀察中還可以發現到,擁有豐富詞彙的程式語言,並且良好掌握該詞彙與語法的價值。英語正是一個有著相當龐大詞彙與誇張語法數量的豐富語言。不少人說如果能簡化詞彙跟語法,會讓英語更加簡單易用。

然而,如果真的將英語縮減,將複雜的語法簡化為更為簡單的結構,的確會讓英語更易學習,但英語傳達資訊的功能也將大大減弱。換言之,為了節省掌握該語言的時間,代價是喪失語言的表達力。


語言大統一?


對於程式語言,我們很難採取和上述同樣方式的思維。因為我們通常不希望在單一程式語言和框架上,比照口語和書寫語言,投入那麼多的心力。然而,程式語言的詞彙越豐富,語法越複雜,也就越具有表達性,對那麼掌握其詞彙與語法的人來說,可讀性也就更高。

不過別擔心,我並非在提倡發展出一個大家都應該學的超複雜程式語言。至少還不是現在。

這種事有賴於人類整體知識水準的提升。

目前我們要重視的,是擁有簡單詞彙、易於理解與學習的程式語言,即使這些語言的表達力比不上較複雜的語言。

最後當大部份的人都知道如何寫程式時,我相信屆時會需要一個語言,對電腦和人類而言,同具有英語和世上其他語言的表達性。

你的想法呢?我們應該有更複雜、更難以掌握的程式語言,以便享有更高的表達能力,還是應該用比較簡單的程式語言,寫出比較複雜又冗長的程式碼?


相關網址:

  1. 如何寫出易懂的程式碼:跟你想的不一樣
    https://simpleprogrammer.com/2013/04/14/what-makes-code-readable-not-what-you-think/



自由軟體鑄造場電子報 : 第 217 期 淺談貢獻者契約在自由開源軟體之應用

分類: 自由專欄