簡體   English   中英

代碼文檔:多少錢太多了?

[英]Code documentation: How much is too much?

您的.NET源代碼文檔中有多少是太多了?

一些背景:我繼承了一個很大的代碼庫,我已經在SO上發布了一些其他問題。 這個代碼庫的一個“特性”是God Class,一個包含大約3000行代碼的單個靜態類,包含幾十個靜態方法。 它是從Utilities.CalculateFYBasedOnMonth()Utilities.GetSharePointUserInfo()Utilities.IsUserIE6() 這些都是不需要重寫的好代碼,只需重構成一組適當的庫。 我已經計划好了。

由於這些方法正在進入一個新的業務層,我在這個項目中的角色是為其他開發人員准備系統以進行維護,我正在考慮可靠的代碼文檔。 雖然這些方法都具有良好的內聯注釋,但它們並不都具有XML注釋形式的良好(或任何)代碼doco。 使用GhostDoc和Sandcastle(或文檔X)的組合,我可以創建一些非常好的HTML文檔並將其發布到SharePoint,這將使開發人員更多地了解代碼的作用,而無需瀏覽代碼本身。

隨着代碼中文檔量的增加,導航代碼變得越困難。 我開始懷疑XML注釋是否會使代碼更難以維護,比如說每個方法更簡單的//comment

這些示例來自Document X示例

        /// <summary>
        /// Adds a new %Customer:CustomersLibrary.Customer% to the collection.
        /// </summary>
        /// <returns>A new Customer instance that represents the new customer.</returns>
        /// <example>
        ///     The following example demonstrates adding a new customer to the customers
        ///     collection. 
        ///     <code lang="CS" title="Example">
        /// CustomersLibrary.Customer newCustomer = myCustomers.Add(CustomersLibrary.Title.Mr, "John", "J", "Smith");
        ///     </code>
        ///     <code lang="VB" title="Example">
        /// Dim newCustomer As CustomersLibrary.Customer = myCustomers.Add(CustomersLibrary.Title.Mr, "John", "J", "Smith")
        ///     </code>
        /// </example>
        /// <seealso cref="Remove">Remove Method</seealso>
        /// <param name="Title">The customers title.</param>
        /// <param name="FirstName">The customers first name.</param>
        /// <param name="MiddleInitial">The customers middle initial.</param>
        /// <param name="LastName">The customers last name.</param>
        public Customer Add(Title Title, string FirstName, string MiddleInitial, string LastName)
        {
            // create new customer instance
            Customer newCust = new Customer(Title, FirstName, MiddleInitial, LastName);

            // add to internal collection
            mItems.Add(newCust);

            // return ref to new customer instance
            return newCust;
        }

和:

    /// <summary>
    /// Returns the number of %Customer:CustomersLibrary.Customer% instances in the collection.
    /// </summary>
    /// <value>
    /// An Int value that specifies the number of Customer instances within the
    /// collection.
    /// </value>
    public int Count
    {
        get 
        {
            return mItems.Count;
        }
    }

所以我想知道你:你是否用XML注釋記錄了所有代碼,目的是使用NDoc(RIP)或Sandcastle這樣的東西? 如果沒有,你如何決定什么獲得文檔,什么沒有? 類似於API的東西顯然會有doco,但是你要將代碼庫移交給另一個團隊進行維護呢?

你覺得我應該怎么做?

沒有人提到你的代碼不需要膨脹,XML文檔可以在另一個文件中:

/// <include file="Documentation/XML/YourClass.xml" path="//documentation/members[@name='YourClass']/*"/>

然后你的Add方法不能在它上面包含額外的XML /注釋,或者你只是喜歡摘要(因為它與單獨的文件合並)。

它比Javadoc和你在PHP / Javascript中找到的衍生物的垃圾格式強大得多(盡管Javadoc為XML語法鋪平了道路)。 此外,可用的工具要優越得多,幫助文檔的默認外觀更易讀,也更容易定制(我可以說,從編寫doclet並將該過程與Sandcastle / DocProject / NDoc進行比較)。

我認為這里的問題很大一部分是MS強加給我們的冗長和苛刻的XML文檔語法(JavaDoc也沒有好多少)。 如何格式化它的問題在很大程度上取決於多少是合適的。

使用XML格式進行注釋是可選的。 您可以使用DOxygen或其他識別不同格式的工具。 或者編寫自己的文檔提取器 - 這並不像你想象的那樣難以做一份合理的工作並且是一種很好的學習體驗。

問題是多少更難。 我認為自編文檔代碼的想法很好,如果你正在挖掘維護一些代碼。 如果您只是一個客戶端,則不需要閱讀代碼來了解給定函數的工作原理。 當然,大量信息隱含在數據類型和名稱中,但有很多信息並非如此。 例如,傳入對象的引用會告訴您預期的內容,但不會告訴您如何處理空引用。 或者在OP的代碼中,如何處理參數開頭或結尾的任何空格。 我認為應該記錄的這類信息遠遠多於通常認可的信息。

對我而言,它需要自然語言文檔來描述函數的目的以及函數的前置和后置條件,其參數和返回值,這些都不能通過編程語言語法表達

在維護新庫的那些和將要消耗新庫的那些庫之間,你正處於一個關鍵的鴻溝。

如果我正在編寫一個新的應用程序並將使用這些標准庫,我應該得到一個穩定的庫二進制文件,只需將它們導入我的應用程序,而不是從一個位置復制源代碼,如果代碼可能會導致問題得到修改。 在這種情況下,除了方法名稱和輸入/輸出參數之外,我將無法訪問任何“自我記錄”功能,如果我使用某種IDE,甚至不會暴露這些功能沒有自動完成功能打開。

所以在上面的示例代碼中,我認為它看起來很好。 事情在代碼本身中並不太冗長,而且名稱是自我記錄的。 另一方面,所有必要的摘要/參數數據都在那里,以便可以構建一個可靠的文檔片段,以允許那些使用庫的人將所有關鍵信息放在指尖。 可悲的是,XML相當臃腫,但總的來說,我認為大多數開發人員可以輕松瀏覽所有摘要內容並查看方法中的實際代碼。

傑夫有一篇關於評論(或者我應該說,不評論)的非常好的文章......

http://www.codinghorror.com/blog/archives/001150.html

我知道似乎我沒有回答這個問題,但我認為代碼應盡可能自我記錄是一個有效的觀點。

我傾向於在自己的代碼中記錄所有公共方法; 使用GhostDoc使這個變得微不足道。 為了減少編輯源代碼時的混亂,我通常只是首先進入“大綱模式”(即使用Visual Studio的Outline> Collapse to definitions命令)來折疊注釋。

我從來沒有嘗試過Sandcastle,但我非常感謝Intellisense為我所評論的方法提供的舒適性。

我總是選擇XML / Javadoc格式的注釋,因為我喜歡能夠以合理的格式瀏覽API文檔(通常是HTML)。

它確實成為瀏覽實際源代碼的問題,但我發現這通常是一個小問題,因為Visual Studio通常非常聰明地根據需要折疊XML注釋。

不要重復自己。

  • 第一個示例應該有一個更好的方法名稱,根本沒有注釋。
  • 第二個例子不應該有評論。

第一個方法的名稱應反映分配了新對象。

如果該行為在整個框架中對於每個添加都是標准的,則應該在更高級別上進行記錄,而不是在此方法API文檔中。 否則,請更改名稱。

評論應該添加信息,而不是將其隱藏在噪音中。 在必要的XML中應該有評論。 並在那里增加價值。

我不想看到:對於名為count的方法,“返回計數”。

熟悉您的代碼庫的人必須清楚地理解所有公共功能,但不必在您的特定部分中,而不必深入研究代碼。

如果你需要寫一個簡短的行來解釋一個函數的作用,你可能很難命名你的函數/類。 在這種情況下,名稱應該是自我解釋的

如果它需要超過1個簡短的句子來解釋,這可能是一個很好的評論

如果它需要一個段落,除了可能不清楚的名字之外,你的功能可能做得太多了。

如果你確定它們是准確的,通常最好在評論方面犯錯誤。 不准確和/或不可維護的評論比沒有評論更糟糕

所以應用這些規則:

在您的第一個示例中:“//創建新客戶實例”是多余的。 代碼很清楚。 其他評論是完美的。 他們澄清了代碼在運行的內容/結果是什么

在您的第二個示例中,評論是浪費精力並使其難以閱讀。 您需要做的就是為函數指定一個正確的名稱。 不是那個模糊的“數”。 這是命名不佳。

我最近進行的一項研究表明,如果你有重要的“指令”,例如,來電者必須在許多規范中做“X”(例如,“這種方法做X意味着Y和Z”),那么風險很大你的讀者會錯過這些指令。事實上,當他們看到很長的文檔時,他們會完全閱讀它。

所以至少,分開重要的東西或使用標記(問我是否使用Java)。

這一切都取決於您的公司使用的標准,但對於我的工作人員,我們將文檔放在每個函數的頂部,如第二個示例中所示(通過按“/”鍵3次,您可以在Visual Studio 2008中執行此操作在任何子或函數的頂部連續!!)。

第一個例子是矯枉過正,尤其是每行評論的底線。 但是,我認為函數頭部的內容可能很有用,因為我們在這里使用它很多。 從許多其他程序員那里我可以看出它似乎有點標准。

我見過編碼標准建議不要評論自我評論代碼和方法重載。 雖然YMMV,這聽起來像是一個很好的方法來擺脫“Field _numberOfCars是一個代表汽車數量的整數”類型的評論,導致過度殺傷。

用於生成文檔的標題中的注釋是一件好事。 在代碼中添加注釋來解釋為什么你正在做你正在做的事情通常也是一件好事。 用冗余的評論來解釋你所做的並不是一件好事

你所展示的是遠遠不夠。 幫自己一個忙,刪除它!

代碼應該首先通過有意義的方法和參數名稱進行自我記錄。 在你展示的例子中;

public Customer Add(標題標題,字符串FirstName,字符串MiddleInitial,字符串LastName)完全可以理解正在發生的事情,就像'Count'一樣。

正如你所指出的那樣,這樣的評論純粹是圍繞着易於閱讀的代碼的噪音 大多數開發人員將盡快開放檢查和使用代碼,而不是通過模糊的自動生成的API文檔。 每次!

順便說一下,根據“清潔代碼”(一本好書,BTW),應該避免在源代碼中嵌入的注釋中使用HTML / XML標記。 即使您的IDE可以在懸停時創建漂亮的文檔,當您瀏覽源時,它也會被認為太分散注意力並且不可讀。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM