五種應該避免的程式碼註釋

maqianmaqian發表於2010-08-10

酷殼: http://CoolShell.cn/

原文: http://coolshell.cn/?p=2746


在酷殼,有很多文章都提到了程式碼註釋,如:《十條不錯的程式設計觀點》、《優質程式碼的十誡》、《整潔程式碼的4個提示》、《惹惱程式設計師的十件事》等等。今天,某國外的程式設計師在這裡列舉五種應該避免的程式註釋,我覺得比較有道理,但我覺得有少數幾個觀點也並不絕對。所以,我把原文的這五種應該避免的程式註釋羅列在下面,並放上原作者和我的個人觀點作為比較。希望對大家有用。

一、自戀型註釋
(注:原文為Proud,我覺得“自戀”更好一點)

public class Program
{
    static void Main(string[] args)
    {
        string message = "Hello World!";  // 07/24/2010 Bob
        Console.WriteLine(message); // 07/24/2010 Bob
        message = "I am so proud of this code!"; // 07/24/2010 Bob
        Console.WriteLine(message); // 07/24/2010 Bob
    }
}原文:這樣的程式設計師對於自己的程式碼改動非常驕傲和自戀,所以,他覺得需在在這些自己的程式碼上標上自己的名字。其實,一個版本控制工具(如:CVS或Subversion)可以完整地記錄下所有的關於程式碼的改動的和作者相關的一切資訊,只不過不是那麼明顯罷了。

陳皓:我同意原文的觀點。在我的團隊裡也有這樣的事情發生。有段時間我認真思考過這樣的事情,是否應該把這樣的事情在程式碼中剷除出去。後來,我覺得,允許這樣的行為並不一定是壞事,因為兩點:

調動程式設計師下屬的積極性可能更為重要。即然,這種方式可以讓程式設計師有驕傲的感覺,能在寫程式碼中找到成就感,為什麼要阻止呢?又不是什麼大問題。
調動程式設計師的負責任的態度。程式設計師敢把自己的名字放在程式碼裡,說明他對這些程式碼的信心,是想向大家展示其才能。所以,他當然知道,如果這段他加入的程式碼有問題的話,他的聲譽必然受到損失,所以,他敢這麼幹,也就表明他敢於對自己的程式碼全面的負責。這不正是我們所需要的?!
所以,基於上述考慮,我個人認為,從程式碼的技術角度上來說,這樣的註釋很不好。但從團隊的激勵和管理上來說,這樣的方式可能也挺好的。所以,我並不阻止也不鼓勵這樣的註釋。關鍵在於其是否能有更好的結果。

二、廢棄程式碼的註釋
public class Program
{
    static void Main(string[] args)
    {
        /* This block of code is no longer needed
         * because we found out that Y2K was a hoax
         * and our systems did not roll over to 1/1/1900 */
        //DateTime today = DateTime.Today;
        //if (today == new DateTime(1900, 1, 1))
        //{
        //    today = today.AddYears(100);
        //    string message = "The date has been fixed for Y2K.";
        //    Console.WriteLine(message);
        //}
    }
}原文:如果某段程式碼不再使用了,那就應該直接刪除。我們不應該使用註釋來標準廢棄的程式碼。同樣,我們有版本控制工具來管理我們的原始碼,在版本控制工具裡,是不可能有程式碼能被真正的物理刪除的。所以,你總是可以從以前的版本上找回你的程式碼的。

陳皓:我非常同意這樣的觀點。只要你是廢棄的,就應該是刪除,而不是註釋掉。註釋並不是用來刪除程式碼的。也許你會爭論到,在迭代開發中,你覺得被註釋的程式碼很有可能在未來會被使用,但現在因為種種問題暫時用不到,所以,你先註釋著,然後等到某一天再enable它。所以你註釋掉一些未來會有的程式。在這樣的情況,你可以註釋掉這段程式碼,但你要明白,這段程式碼不是“廢棄”的,而是“臨時”不用的。所以,我在這裡提醒你,請不要教條式地在你的程式原始碼中杜絕這樣的註釋形式,是否“廢棄”是其關鍵。

三、明顯的註釋
public class Program
{
    static void Main(string[] args)
    {
        /* This is a for loop that prints the
         * words "I Rule!" to the console screen
         * 1 million times, each on its own line. It
         * accomplishes this by starting at 0 and
         * incrementing by 1. If the value of the
         * counter equals 1 million the for loop
         * stops executing.*/
        for (int i = 0; i < 1000000; i++)
        {
            Console.WriteLine("I Rule!");
        }
    }
}原文:看看上面的例子,程式碼比註釋還容易讀。是的,大家都是程式設計師,對於一些簡單的,顯而易見的程式邏輯,不需要註釋的。而且,你不需要在你的註釋中教別人怎麼程式設計,你這是在浪費時間去解釋那些顯而易見的東西。你應該用註釋去解釋你的程式碼功能,原因,想法,而不是程式碼本身。

陳皓:非常同意。最理解的情況是你的程式碼寫得直接易讀,程式碼本身就是自解釋的,根本不需要註釋。這是最高境界。註釋應該說明下面的程式碼主要完成什麼樣的功能,為什麼需要他,其主要演算法怎麼設計的,等等。而不是解釋程式碼是怎麼工作的。這點很多新手程式設計師都做得不夠好。別外,我需要指出的是,程式碼註釋不宜過多,如果太多的話,你應該去寫文件,而不是寫註釋了。

四、故事型註釋
public class Program
{
    static void Main(string[] args)
    {
       /* I discussed with Jim from Sales over coffee
        * at the Starbucks on main street one day and he
        * told me that Sales Reps receive commission
        * based upon the following structure.
        * Friday: 25%
        * Wednesday: 15%
        * All Other Days: 5%
        * Did I mention that I ordered the Caramel Latte with
        * a double shot of Espresso?
       */
        double price = 5.00;
        double commissionRate;
        double commission;
        if (DateTime.Today.DayOfWeek == DayOfWeek.Friday)
        {
            commissionRate = .25;
        }
        else if (DateTime.Today.DayOfWeek == DayOfWeek.Wednesday)
        {
            commissionRate = .15;
        }
        else
        {
            commissionRate = .05;
        }
        commission = price * commissionRate;
    }
}原文:如果你不得不在你的程式碼註釋中提及需求,那也不應該提及人名。在上面的示例中,好像程式想要告訴其它程式設計師,下面那些程式碼的典故來自銷售部的Jim,如果有不懂的,你可以去問他。其實,這根本沒有必要在註釋中提到一些和程式碼不相干的事。

陳皓:太同意了。這裡僅僅是程式碼,不要在程式碼中摻入別的和程式碼不相干的事。這裡你也許會有以下的爭辯:

有時候,那些所謂的“高手”逼著我這麼幹,所以,我要把他的名字放在這裡讓所有人看看他有多SB。
有時候,我對需求並不瞭解,我們應該放一個聯絡人在在這裡,以便你可以去詢問之。
對於第一點,我覺得這是一種情緒化。如果你的上級提出一些很SB的想法,我覺得你應該做的是努力去和他溝通,說明你的想法。如果這樣都不行的話,你應該讓你的經理或是那個高手很正式地把他的想法和方案寫在文件裡或是電子郵件裡,然後,你去執行。這樣,當出現問題的時候,你可以用他的文件和郵件作為你的免責證據,而不是在程式碼裡幹這些事。

對於第二點,這些需求的聯絡人應該是在需求文件中,如果有人有一天給你提了一個需求,你應該把其寫在你的需求文件中,而不是你的程式碼裡。要學會使用流程來管理你的工作,而不是用註釋。

最後,關於故事型的註釋,我需要指出也有例外的情況,我們團隊中有人寫註釋喜歡在註釋或文件裡寫一些名人名言(如 22條經典的程式設計引言,程式設計引言補充,Linus Torvalds 語錄 Top 10 ),甚至寫一些小笑話,幽默的短句。我並不鼓勵這麼做,但如果這樣有利於培養團隊文化,有利於讓大家對工作更感興趣,有利於大家在一種輕鬆愉快的環境下讀/寫程式碼,那不也是挺好的事嗎?

另外,做為一個管理者,有時候我們應該去看看程式設計師的註釋,因為那裡面可能會有程式設計師最直實的想法和情緒(程式設計師嘴最髒??)。瞭解了他們的想法有利於你的管理。

五、“TODO”註釋
public class Program
{
    static void Main(string[] args)
    {
       //TODO: I need to fix this someday – 07/24/1995 Bob
       /* I know this error message is hard coded and
        * I am relying on a Contains function, but
        * someday I will make this code print a
        * meaningful error message and exit gracefully.
        * I just don’t have the time right now.
       */
       string message = "An error has occurred";
       if(message.Contains("error"))
       {
           throw new Exception(message);
       }
    }
}原文:當你在初始化一個專案的時候,TODO註釋是非常有用的。但是,如果這樣的註釋在你的產品原始碼中出現了N多年,那就有問題了。如果有BUG要被fix,那就Fix吧,沒有必要整一個TODO。

陳皓:是的,TODO是一個好的標誌僅當存在於還未release的專案中,如果你的軟體產品都release了,你的程式碼裡還有TODO,這個就不對了。也許你會爭辯說,那是你下一個版本要乾的事。OK,那你應該使用專案管理,或是需求管理來管理你下一個版本要乾的事,而不是使用程式碼註釋。通常,在專案release的前夕,你應該走查一下你程式碼中的TODO標誌,並且做出決定,是馬上做,還是以後做。如果是以後做,那麼,你應該使用專案管理或需求管理的流程。

上述是你應該避免使用的註釋,以及我個人的一些觀點,也歡迎你留下你的觀點!

 

本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/haoel/archive/2010/08/02/5782907.aspx

相關文章