讓程序更容易理解:13個(gè)代碼注釋的小技巧

2010-08-28 10:54:29來源:西部e網(wǎng)作者:

這篇文章是由José M. Aguilar在他卓越的博客中以西班牙語的形式首發(fā),其后Timm Martin在獲得Aguilar先生的授權(quán)下,對該文章進(jìn)行翻譯、修改,并且在DevTopics上發(fā)布。

以下13個(gè)小技巧可以使得你的代碼在長時(shí)間內(nèi)依然能夠保持容易理解和維護(hù)。

1. 對不同級別的代碼進(jìn)行注釋

對于不同級別的代碼塊,要使用統(tǒng)一的方法來進(jìn)行注釋。例如:

    * 對于每一個(gè)類,需要包含一段簡明扼要的描述,作者和上一次修改的時(shí)間
    * 對于每一個(gè)方法,需要包含這個(gè)方法的用途,功能,參數(shù)以及返回結(jié)果

當(dāng)你在一個(gè)團(tuán)隊(duì)里面的時(shí)候,采用一套注釋的標(biāo)準(zhǔn)是非常重要的。當(dāng)然,使用一種大家都認(rèn)可的注釋約定和工具(例如C#的XML注釋和Java的Javadoc)在一定程度上能推動這項(xiàng)任務(wù)。

2. 使用段落注釋

首先把代碼塊分解成多個(gè)“段落”,每一個(gè)段落都執(zhí)行單一的任務(wù);然后在每一個(gè)“段落”開始之前添加注釋,告訴閱讀代碼的人接下來的這段代碼是干什么用的

    // 檢查所有記錄都是正確的
    foreach (Record record in records)
    {
        if (rec.checkStatus()==Status.OK)
        {
            . . .
        }
    }
    // 現(xiàn)在開始進(jìn)行處理
    Context ctx = new ApplicationContext();
    ctx.BeginTransaction();
    . . .

3. 對齊注釋行

對于那些在行末寫有注釋的代碼,應(yīng)該對齊注釋行來使得方便閱讀

    const MAX_ITEMS = 10; // maximum number of packets
    const MASK = 0x1F;    // mask bit TCP

有些開發(fā)人員使用tab來對齊注釋,而另外一些人會用空格來對齊。由于tab在不同的編輯器和集成開發(fā)環(huán)境中會有所不同,所以最佳的方法是使用空格來對齊注釋行。

4. 不要侮辱閱讀者的智慧

要避免沒用的注釋,例如

    if (a == 5)        //如果a等于5
        counter = 0    //把counte設(shè)為0

這不單把時(shí)間浪費(fèi)在寫沒用的注釋上面,同時(shí)也在分散讀者的注意力。

5. 要有禮貌

應(yīng)當(dāng)避免沒有禮貌的注釋,例如“要注意一些愚蠢的用戶會輸入一個(gè)負(fù)數(shù)”,或者“修正由菜鳥工程師寫的愚蠢得可憐的代碼而導(dǎo)致的副作用”。這樣的注釋對于代碼的寫注釋的人來說并沒有任何好處,同時(shí)你永遠(yuǎn)都不會知道將來這些注釋會被誰來閱讀,你的老板,一個(gè)客戶或者是剛才被你數(shù)落的愚蠢得可憐的工程師。

6. 直截了當(dāng)

不要在注釋里面寫過多的廢話。避免在注釋里面賣弄ASCII藝術(shù),寫笑話,作詩和過于冗長。簡而言之就是保持注釋的簡單和直接。

7. 使用統(tǒng)一的風(fēng)格

有些人覺得注釋應(yīng)該讓非程序員也能看懂。另外一些人覺得注釋需要面對的讀者只是程序員。無論如何,正如Successful Strategies for Commenting Code中所說的,最重要的是注釋的風(fēng)格需要統(tǒng)一,并且總是面向相同的讀者。就自己而論,我懷疑非程序員是否會去讀代碼,所以我覺得注釋應(yīng)該面向程序員來寫。

8. 在內(nèi)部使用特殊的標(biāo)簽

當(dāng)你在一個(gè)團(tuán)隊(duì)里工作的時(shí)候,采用一組一致的標(biāo)簽?zāi)軒椭煌某绦騿T溝通。例如,很多團(tuán)隊(duì)會采用“TODO”標(biāo)簽來表示一段尚未完成的代碼

    int Estimate(int x, int y)
    {
        // TODO: implement the calculations
        return 0;
    }

標(biāo)簽注釋并不會解釋代碼,它們尋求注意或者是傳遞信息。但是如果適當(dāng)?shù)厥褂眠@種技術(shù),要記住跟進(jìn)這段代碼并且完成該標(biāo)簽傳遞的任務(wù)。

9. 在寫代碼的同時(shí)添加注釋

當(dāng)你在寫代碼而且記憶猶新的同時(shí)就添加注釋。如果等到項(xiàng)目后期才添加注釋,會讓你事倍功半。“我沒有時(shí)間寫注釋”,“我的時(shí)間很緊迫”和“項(xiàng)目已經(jīng)延遲了”,這些都是不寫注釋的常見借口。有些工程師覺最佳的解決方法是“注釋先行”。例如:

    public void ProcessOrder()
    {
        // Make sure the products are available
        // Check that the customer is valid
        // Send the order to the store
        // Generate bill
    }

10. 把自己想象為注釋的讀者(事實(shí)上就是如此)

當(dāng)你正在給代碼寫注釋的時(shí)候,不僅僅為日后維護(hù)你的代碼的開發(fā)者考慮,同時(shí)也設(shè)想一下如果自己就是注釋的讀者。Phil Haack曾經(jīng)說過:

    “一旦一行代碼被敲到文件中, 你就已經(jīng)要開始維護(hù)那一行代碼了!

所以,我們自己就是好(或者壞)注釋的第一個(gè)受益者(或者受害者)。

11. 更新代碼的時(shí)候要更新注釋

如果注釋沒有隨著代碼的修改而更新,那么這些注釋將是毫無意義的。代碼和注釋需要同步,否則注釋只會讓維護(hù)代碼的開發(fā)者更加痛苦。需要特別注意的是,一些重構(gòu)的工具會自動更新代碼,但是卻沒有自動更新注釋,那么注釋就自然而然地過期作廢了。

12. 良好可讀性代碼是注釋的金科玉律

對于很多開發(fā)者來說,一個(gè)基本的原則就是:讓代碼自己描述自己。雖然有人懷疑這是由不喜歡寫注釋的程序員所倡導(dǎo)的一場運(yùn)動,但是無需解釋的代碼有很大的好處,這些代碼更加容易理解甚至讓注釋變得沒有必要。例如,在我的文章Fluid Interfaces中就給大家展示了什么是清晰的無需解釋的代碼。

    Calculator calc = new Calculator();
    calc.Set(0);
    calc.Add(10);
    calc.Multiply(2);
    calc.Subtract(4);
    Console.WriteLine( “Result: {0}”, calc.Get() );

在這個(gè)例子里面,注釋就像是違反了第4條技巧那樣,變得毫無必要。要寫出可讀性好的代碼,你需要使用適當(dāng)?shù)拿绞剑ㄔ诮?jīng)典的Ottinger’s Rules中有闡述),保證恰當(dāng)?shù)目s進(jìn),并且采用編碼風(fēng)格指導(dǎo)。如果代碼不遵守這條技巧,那么注釋看起來就好像是為自己不好的代碼的寫道歉信一樣。

13. 跟你的同事分享這些技巧

雖然從第10條技巧中我們已經(jīng)知道了自己就是好注釋的得益者,但是這些技巧對于所有的開發(fā)者來說都是很有幫助的,尤其是整個(gè)團(tuán)隊(duì)都有相同共識的情況下。因此,大方地跟你的同事去分享這些技巧,讓我們寫出更加容易理解和維護(hù)的代碼。

關(guān)鍵詞:注釋代碼

贊助商鏈接: