代码文档:多少钱太多了?

时间:2008-11-13 21:04:41

标签: .net sandcastle xml-comments code-documentation ndoc

.NET源代码文档中的代码文档太多了?

一些背景知识:我继承了一个很大的代码库,我已经在SO上发布了一些其他问题。这个代码库的一个“特性”是God Class,一个包含大约3000行代码的单个静态类,包含几十个静态方法。这是从Utilities.CalculateFYBasedOnMonth()Utilities.GetSharePointUserInfo()Utilities.IsUserIE6()的所有内容。这是doesn't need to be rewritten的所有优秀代码,只是重构为一组适当的库。我计划好了。

由于这些方法正在进入一个新的业务层,而我在这个项目中的角色是为其他开发人员准备系统以进行维护,我正在考虑可靠的代码文档。虽然这些方法都具有良好的内联注释,但它们并不都具有XML注释形式的良好(或任何)代码doco。使用GhostDoc和Sandcastle(或文档X)的组合,我可以创建一些非常好的HTML文档并将其发布到SharePoint,这将使开发人员更多地了解代码的功能,而无需浏览代码本身。

随着代码中文档量的增加,导航代码变得越困难。我开始怀疑XML注释是否会使代码更难以维护,比如每个方法更简单//comment

这些示例是from the Document X sample

        /// <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,但是你要将代码库移交给另一个团队进行维护呢?

你认为我应该怎么做?

14 个答案:

答案 0 :(得分:8)

没有人提到你的代码不需要膨胀,XML文档可以在另一个文件中:

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

然后你的Add方法上面不能包含额外的XML /注释,或者你只是喜欢摘要(因为它与单独的文件合并)。

它比Javadoc和你在PHP / Javascript中找到的衍生物的垃圾格式强大得多(尽管Javadoc为XML语法铺平了道路)。此外,可用的工具要优越得多,帮助文档的默认外观更易读,也更容易定制(我可以说是通过编写doclet并将该过程与Sandcastle / DocProject / NDoc进行比较)。

答案 1 :(得分:5)

我认为问题的一个很好的部分是MS强加给我们的冗长和苛刻的XML文档语法(JavaDoc也没有好多少)。如何格式化它的问题在很大程度上取决于多少是合适的。

使用XML格式进行注释是可选的。您可以使用DOxygen或其他识别不同格式的工具。或者编写自己的文档提取器 - 这并不像你想象的那样难以做一份合理的工作并且是一种很好的学习经历。

有多难的问题。我认为自编文档代码的想法很好,如果你正在挖掘维护一些代码。如果您只是一个客户端,则不需要阅读代码来了解给定函数的工作原理。当然,大量信息隐含在数据类型和名称中,但有很多信息并非如此。例如,传入对象的引用会告诉您预期的内容,但不会告诉您如何处理空引用。或者在OP的代码中,如何处理参数开头或结尾的任何空格。我相信这类信息应该记录得比通常认可的更多。

对我而言,它需要自然语言文档来描述函数的用途以及函数的前后条件,其参数和返回值,它们无法通过编程语言语法表达< / em>的

答案 2 :(得分:3)

在维护新库的那些和将要使用新库的那些库之间,你正处于一个关键的鸿沟。

如果我正在编写一个新的应用程序并将使用这些标准库,我应该得到一个稳定的库二进制文件,只需将它们导入我的应用程序,而不是从一个位置复制源代码并可能导致问题如果代码被修改。在这种情况下,除了方法名称和输入/输出参数之外,我将无法访问任何“自我记录”功能,如果我使用某种IDE,甚至不会暴露这些功能没有打开自动完成功能。

所以在上面的示例代码中,我觉得它看起来很好。事情在代码本身中并不太冗长,而且名称是自我记录的。另一方面,所有必要的摘要/参数数据都在那里,以便可以构建一个可靠的文档片段,以允许那些使用库的人将所有关键信息放在指尖。可悲的是,XML相当臃肿,但大体上我认为大多数开发人员可以轻松浏览所有摘要内容并查看方法中的实际代码。

答案 3 :(得分:1)

Jeff在这里发表了一篇关于评论(或者我应该说,不评论)的非常好的文章......

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

我知道我似乎没有回答这个问题,但我认为代码应尽可能自我记录是有效的。

答案 4 :(得分:1)

我倾向于在自己的代码中记录所有公共方法;使用GhostDoc使这个变得微不足道。为了减少编辑源代码时的混乱,我通常只是首先进入“大纲模式”(即使用Visual Studio的大纲&gt;折叠到定义命令)来折叠注释。

我从未尝试过Sandcastle,但我非常感谢Intellisense为我所评论的方法提供的舒适感。

答案 5 :(得分:1)

我总是选择XML / Javadoc格式的评论,因为我喜欢能够以合理的格式浏览API文档(通常是HTML)。

它确实成为浏览实际源代码的问题,但我发现这通常是一个小问题,因为Visual Studio通常非常聪明地根据需要折叠XML注释。

答案 6 :(得分:1)

不要重复自己。

  • 第一个示例应该有一个更好的方法名称,根本没有注释。
  • 第二个例子不应该有评论。

第一个方法的名称应反映出已分配新对象。

如果该行为在每个添加的整个框架中都是标准的,则应该在更高级别上进行记录,而不是在此方法API文档中。否则,请更改名称。

评论应该添加信息,而不是将其隐藏在噪音中。在必要的XML中应该有评论。并且它们增加了价值。

我不想看到: 对于名为count的方法,“返回计数”。

答案 7 :(得分:1)

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

如果你需要写一个简短的行来解释函数的作用,你可能很难命名你的函数/类。在这种情况下,名称应该是自我解释的

如果需要超过1个简短的句子来解释,这可能是一个很好的评论

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

通常最好在评论方面犯错如果你确定它们是准确的。不准确和/或不可维护的评论比没有评论更糟糕

所以应用这些规则:

在您的第一个示例中:“//创建新客户实例”是多余的。代码很清楚。其他评论是完美的。他们澄清了代码在运行的内容/结果是什么

在你的第二个例子中,评论是浪费精力并使其难以阅读。您需要做的就是为函数指定一个正确的名称。不是那个模糊的“数”。那是命名不好。

答案 8 :(得分:1)

我最近进行的一项研究表明,如果你有重要的“指令”,例如,来电者必须在许多规范中做“X”(例如,“这种方法做X,这意味着Y和Z”),有一个非常您的读者会错过指令的风险很高。事实上,当他们看到很长的文档时,他们会跳过阅读它。

至少,将重要内容分开或使用标记(问我是否使用Java)。

答案 9 :(得分:1)

这一切都取决于您的公司使用的标准,但对于我的工作人员,我们在每个函数的顶部记录,例如在您的第二个示例中(通过点击“/”,您可以在Visual Studio 2008中执行此操作)在任何子或函数顶部连续3次键!!)。

第一个例子是矫枉过正,尤其是每行评论的底线。但是,我认为函数头部的内容可能很有用,因为我们在这里使用它很多。从许多其他程序员那里可以看出它似乎有点标准。

答案 10 :(得分:0)

我见过编码标准建议不要评论自我评论代码和方法重载。虽然是YMMV,但这听起来像是一个很好的方法来摆脱“Field _numberOfCars是一个代表汽车数量的整数”类型的评论,导致过度杀伤。

答案 11 :(得分:0)

生成文档的标题中的注释是一件好事。在代码中添加注释来解释为什么你正在做你正在做的事情通常也是一件好事。用冗余的评论来解释你所做的并不是一件好事

答案 12 :(得分:0)

你所展示的是远远不够。帮自己一个忙,然后将其删除!

代码应该首先通过有意义的方法和参数名称进行自我记录。在你展示的例子中;

公共客户添加(标题标题,字符串FirstName,字符串MiddleInitial,字符串LastName)完全可以理解正在发生的事情,就像'计数'一样。

正如您所指出的那样,对此进行评论纯粹是噪声围绕着其他易于阅读的代码。大多数开发人员将尽快开放检查和使用代码,而不是通过模糊的自动生成的API文档。每次!

答案 13 :(得分:0)

顺便说一下,根据“清洁代码”(一本好书,BTW),应该避免在源代码中嵌入的注释中使用HTML / XML标记。即使您的IDE可以在悬停时创建漂亮的文档,当您浏览源时,它也会被认为太分散注意力并且不可读。