如果有許多程式人不喜歡撰寫文件,那麼應該也有為數不少的程式人,不喜歡為他們所寫下的程式碼撰寫註解。撰寫註解和文件,時常被程式人視為浪費時間。尤其註解不像文件,幾乎都會被列在專案的工作分解結構(WBS)中,更加不視為份內必要的工作,使得註解的地位,似乎成了軟體開發工作中的雞肋。倘若有,好像會覺得心安一點;倘若沒有,彷彿也無所謂,對的程式碼還是依舊正常地起作用。

註解是程式的一部分,而非獨立於程式碼之外的組成
雖然有些管理者腦海裡,都有一個大略的印象──寫下越多的註解,就越能夠提升程式碼的可讀性,他們或許會要求程式人盡可能地撰寫註解,甚至還會訂下某些撰寫的標準,但因為許多管理者本身,也不知道什麼是看待註解的正確態度,反而訂下許多簡直是莫名其妙的規矩,更加深了程式人對寫註解反感。

上述兩項一般人的誤會:註解是程式人額外的負擔,對於工作的完成沒有太多幫助,以及要求程式人撰寫越多的註解,就越能確保程式碼的可讀性。

我們所能接觸到的所有程式語言,幾乎都提供了註解的語法,這足以證明它在程式設計活動中的重要性。而事實上,註解應當被視為是程式的一部分,而非獨立於程式碼之外的組成。

註解是在補充程式碼的不足之處
要更妥善地運用註解,就必須先認識到,它是在補充程式碼的不足之處,所以兩者有點互補的關係,當程式碼本身的說明力越高時,那麼所需的註解也就越少;反之,所需的註解量也就越多。之所以需要註解,是因為程式語言語法僅能有限地表達,需要利用人類的自然語言補充。
能自我說明(Self-Documented)的程式碼,正是一種具有高說明力的程式碼。在理想的情況下,具這種能力的程式碼,單靠程式碼本身,便足以表示撰寫者期望讀者了解的部分。也就是說,這樣的程式碼毋需為它標上註解,便足以提供極高的說明能力。

因此,註解量究竟多不多,並不是一個關鍵的判斷指標。有時候,糟糕的程式碼反而需要更多的註解。紊亂的結構、不一致又不具意思的變數函式命名,再上混雜在一塊的一堆程式碼,即使搭配大量的註解,閱讀起來想必仍舊令人十分頭痛。當你看到程式人在程式碼間穿插著滿滿的註解時,或許反而更應該感到憂心。

究竟需要多少的註解量,取決於程式碼的品質。良好的程式碼,具有妥善且一致的命名、排版、風格及各式的寫作習慣。而好的設計,多半都具有簡潔、清晰與易懂的本質。你或許會為變數、函式或類別寫下註解,藉以說明它們的作用。但是,倘若能為它們取一個好名字,在程式人間共通的隱喻(Metaphor)下,這名字將使變數、函式或類別的作用不言可喻。而註解存在的需要性,也就因為良好的命名而消除。

如果程式充滿了太多間接、隱諱的設計,那麼程式碼便形同搭建起迷宮,需要更多的註解扮演指引的作用,才能讓讀者順利從中脫困。相反的,優雅的設計通常本身便充滿了直覺,毋需太多註解補充,便足以充分表達。

註解應該解釋「程式碼為什麼要這麼寫」
需要重構的程式碼,多半在重構後,都能夠提升程式碼的說明力,例如將一個大型的函式,拆解成若干個小型的函式,並賦予適宜的名稱,將使程式碼更容易明白。你應該盡可能地先提升程式碼的品質,接著才是輪到註解登場的時機。

許多人為了寫註解而寫,他們並不試著明白內容應該寫什麼。例如,時常看到的只是程式碼的「換句話說」。等於多此一舉似地表達了讀者讀了程式碼之後也同樣能夠明白的事情。舉個誇張的例子:
double f = d*2; // 將 f 的值設為 d 值的兩倍
「將 f 的值設為 d 值的兩倍」是一般讀者讀了程式碼後即能明白的事實,並不需要額外的註解。在這個誇張的例子中,程式人浪費了時間寫註解,卻沒有為程式增加更多的說明力。其實你應該利用註解去解釋一些單從程式碼看不出來,或者是不易看出來的部分。

註解應該解釋「程式碼為什麼要這麼寫」,而不是「程式碼究竟寫些什麼」。程式碼的內容,很容易從程式碼本身讀懂,但讀者不容易在一時之間明白你「為什麼」要這麼寫。

例如,在一個排序的函式中,它在元素個數小於7時會使用Insertion Sort,而在元素個數大於7時,則會使用Quick Sort。你並不需要寫下註解來說明這樣的事情,因為讀者閱讀程式碼時便能明白到這一層。那麼,註解應該寫些什麼呢?像「當元素個數小於7時,Insertion Sort運作較快,故使用Insertion Sort,反之則使用Quick Sort。」這樣的註解,說明了程式碼「為什麼」要這麼寫,而不單只是表面的「寫了什麼」。

寫註解的重要態度:站在讀者的立場
撰寫註解時,有一個很重要的態度:站在讀者的立場來寫。你要設定所寫註解的對象,並且猜想閱讀者的心,進而運用註解滿足閱讀者的需求。程式碼的讀者可能是和你合作的同事、日後接手程式碼的人,更有可能是你自己。

當你撰寫程式碼時,你必須持續地在心裡想著「如果閱讀者看到我所寫下的程式碼,他是否能夠明白這段程式碼想要達成的作用?他是否能夠明白此刻我為什麼要這麼寫?」倘若不行,你需改用其他改寫程式碼的方式,使得讀者能夠明白。倘若你找不到更好的設計,或更好的寫作方式,使得程式碼完全能自我說明,那麼就是撰寫註解的時機了,你可以利用註解補充在程式碼之外想要表達的資訊。

此外,有些文件產生工具,可以剖析固定的註解格式,藉以產生相對應的文件。例如javadoc便可以剖析Java原始檔,針對類別及函式的特定註解,並產生出十分實用的API文件。此類的註解,不僅有利於他人讀者閱讀,也有助於自動化產生說明文件。

不要在註解標示無用程式碼,或者苛求形式美觀
有些人利用註解標示日後幾乎無用或暫時無用的程式碼,千萬別這麼做,那會讓程式碼太過混亂。也有人在開始撰寫程式碼時發下宏願,立志要讓自己的註解看起來漂漂亮亮,這也請適可而止!雖然註解本身也需要有一致而且清晰的形式,但這不意謂著,需要花太多心力將它編排得十分美觀。註解撰寫必須不能成為一件負擔太重的工作,因為這會使得你無法持之以恆。

另外在註解中,你不應該寫下一些該留在版本控制系統上的資訊。
例如,修正的記錄。有許多程式人會在程式碼中加上註解,說明修改的歷程,包括修改日期、修改者、為什麼要修改、修改了什麼等。這些應該是記錄到版本控制系統上的資訊。此外,當你修改程式碼時,請千萬要記得同步修改註解,使這二者隨時保持一致。

沒有人永遠能夠完全回到自己撰寫某一段程式碼時的心境,所以也沒有人能夠完全回憶起過去究竟為什麼要這麼寫程式碼。基於隨時能快速回復記憶,也基於團隊合作時的程式碼共享,撰寫註解絕對十分重要,而且有實際功用的工作。重點不在於寫下多少,而是在於註解與程式碼是否能相搭配。好的註解就和好程式碼一樣,不僅形式一致而且清晰。總之,好的註解從閱讀者的立場切入,並且切合閱讀者的心。

作者簡介:
王建興
清華大學資訊工程系的博士研究生,研究興趣包括電腦網路、點對點網路、分散式網路管理、以及行動式代理人,專長則是Internet應用系統的開發。曾參與過的開發專案性質十分廣泛而且不同,從ERP、PC Game到P2P網路電話都在他的涉獵範圍之內。

熱門新聞

Advertisement