假设我正在开发一个相对较大的项目。我已经用Doxygen记录了我所有的类和函数,但是,我有个主意在每个源代码文件上放一个“程序员注释”。

其背后的主意是用外行的术语解释一个特定的类起作用(不仅是为什么大多数注释都起作用)。换句话说,是给其他程序员一个类的工作方式的另一种观点。

例如:

/*
 * PROGRAMMER'S NOTES:
 *
 * As stated in the documentation, the GamepadManager class 
 * reads joystick joystick input using SDL and 'parses' SDL events to
 * Qt signals.
 *
 * Most of the code here is about goofing around the joystick mappings.
 * We want to avoid having different joystick behaviours between
 * operating systems to have a more integrated user experience, since
 * we don't want team members to have a bad surprise while
 * driving their robots with different laptops.
 *
 * Unfortunately, we cannot use SDL's GamepadAPI because the robots
 * are interested in getting the button/axes numbers, not the "A" or
 * "X" button.
 *
 * To get around this issue, we created a INI file for the most common 
 * controllers that maps each joystick button/axis to the "standard" 
 * buttons and axes used by most teams. 
 *
 * We choose to use INI files because we can safely use QSettings
 * to read its values and we don't have to worry about having to use
 * third-party tools to read other formats.
 */


新程序员/贡献者更容易理解大型项目的好方法?除了保持一致的编码风格和“标准”目录组织外,针对这些情况还存在任何“标准”或建议吗?

评论

一定不行。如果您的代码不可读,文档将无济于事。

@jeffo-问题在于花时间去做一次可能会发生一次。保持代码可读性的时间是随着时间的流逝。我去过这类文档的地方,这些文档是在项目年轻时或完美主义者Joe仍在团队中时完成的。然后它被放弃了,评论流连忘返,不再准确。

至少在更高层次上,对项目的功能,工作原理以及在架构中进行了哪些折衷的代码外散文描述是无价的。对于新手来说,阅读文档之前必须阅读此类文档。网上有很多关于我的方法过于草率的胡说八道,虽然最初的弓形文档和不断发展的弓形文档确实无法对齐,但是散文描述是必要的任何人都可以快速掌握庞大而重要的代码库。这是一个(较差的)示例:zxq9.com/erlmud/html/001-002_architecture.html

@Telastyn:这与代码是否可读无关(我希望是这样)。记录设计基本原理绝对重要。

@Telastyn:是的,也许。我个人会用一个独立的文档编写它。但是源文件顶部的注释块还不错。

#1 楼

这太棒了。我希望更多的软件开发人员花时间和精力来做到这一点。它:


用简单的英语陈述该类的功能(即它的责任),
提供有关该代码的有用的补充信息,而无需重复逐字地写出该代码已经说过的内容,
概述了一些设计决策及其做出的原因,并且
突出了可能由下一个阅读您的代码的人想到的一些陷阱。

,很多程序员都加入了这个阵营。 “如果代码编写正确,则不必记录在案”。不对。代码类,方法,模块和其他工件之间存在许多隐含的关系,这些关系仅通过阅读代码本身就不明显。

有经验的编码人员可以精心设计出具有清晰,易于理解的架构的设计,没有文档就很明显。但是您实际上看到过多少个这样的程序?

评论


以及为什么“神话人月”成为一个自我实现的预言,没有人花时间为新开发人员写出所有这些内容,因为他们对新开发人员的想法是新鲜的,并且项目没有落伍。

– JeffO
2015年8月1日,下午1:34

我同意您在这里提出的所有观点。我不喜欢OP在他的帖子中使用的术语,即班级的工作方式。这随着时间和维护而改变。尽管我的团队没有在源代码中提及以上内容。我们维护一个带有决策的Wiki,并将关于设计决策的闲置渠道讨论复制到文档中(我们提供了从决策摘要和结论到原始注释的链接,因此我们不必重新散列旧的决策)。一切都在github中完成(所以都放在一个地方)。

–马丁·约克
2015年8月2日,0:07



我唯一的问题是在全球范围内应用。此类非常复杂,有一些陷阱,很显然它确实有用(尽管您最终还是要处理Comment Rot)。当一个班级更加明显时,评论可能会变得多余。

–deworde
2015年8月3日在10:53



“经验丰富的编码人员可以精心设计出具有清晰,易于理解的架构的设计,而无需编写文档就可以很容易地理解。但是实际上您看到了多少个这样的程序。”确实如此,文档的质量永远不会比编码。架构良好的代码往往具有良好的文档(即使毫无意义)。架构不良的代码的注释如“ x递增1”

–deworde
15年8月3日在15:12

我绝对同意这个答案,如果我在代码中找到类似OP的示例,我将非常高兴。只需添加一个即可:考虑在评论中添加一个日期,以向最终读者提示描述的新鲜度,并在每次更新文本时对其进行更新。

– Svalorzen
15年8月4日在8:38

#2 楼

使用大型代码库的关键是不必阅读整个代码库即可进行更改。为了使程序员能够快速找到他要查找的代码,应该对代码进行组织并且使组织清晰可见。也就是说,代码中的每个逻辑单元,从可执行文件,库,命名空间,到单个类,都应有明确的责任。因此,我不仅要记录源文件,还要记录它们所在的目录。

您的程序员说明也为设计决策提供了背景信息。尽管这可能是有价值的信息,但我会将其与责任说明分开(以使读者能够选择是否要阅读类的责任或其设计原理),并将其移至与它描述的来源接近的地方。尽可能地,以最大程度地在代码更新时更新文档(仅当我们可以相信文档的准确性时文档才有用-过时的文档可能比没有文档更糟糕!)。

也就是说,文档应该保持DRY,即不要重复可能已经用代码表达或已经在其他地方描述的信息(诸如“作为文档说明”之类的警告标志)。尤其是,将来的维护者将精通项目的编程语言,因为他们只有英文。用注释对实现进行释义(当人们为自己的文档感到骄傲时,我经常会看到它)没有任何好处,并且可能与实现有所不同,尤其是在文档与它描述的代码不符的情况下。

最后,应在整个项目中对文档的结构进行标准化,以便每个人都可以找到它(这是错误跟踪中Peter文档的一团糟,Wiki中的Sue,自述文件中的Alan和John在源代码中...)。

评论


您的第一句话就是我对此的看法。大型代码库应由许多较小的组件组​​成,在这些组件中,新程序员可以可靠地更改一个代码,而不会危及其他代码。

–乔恩·切斯特菲尔德
15年8月2日在22:47

将其尽可能靠近其描述的源代码,以最大程度地在代码更新时更新文档。这是宝贵的经验。

–laike9分钟
15年8月7日,下午5:38

将DRY作为文档指南非常重要!这将自动设置焦点权,并禁止著名的令人讨厌的“ // x递增1”注释。

–汉斯·彼得·斯托尔
2015年8月10日在12:23



#3 楼

我不同意这是一个很好的方法,主要是由于


重构项目时,移动方法会导致文档中断。 ,这将导致混乱,而不是帮助理解代码。

如果您对每种方法的每个单元都有单元测试/每个模块的集成测试,那么与之相比,它将是一个更易于维护和易于理解的自我文档。代码注释。

是的,拥有适当的目录结构肯定会有所帮助。

评论


测试+1是理解代码库的最佳方法。单元测试,集成测试,验收测试都讲述了该应用程序应该如何工作以及如何使用的故事。

– BZink
2015年8月6日17:56

#4 楼

我个人是高级设计文档的爱好者-最好在编写任何代码之前编写该文档,该文档提供了设计概述以及类和资源的列表。自上而下的设计极大地简化了工作-您的操作可能是“游戏引擎->硬件->控制器->游戏杆”;因此,一个新的程序员告诉“修复'xyz控制器上的'a'按钮”至少会知道从哪里开始查找。因此,即使是中等规模的项目,仅找到正确的文件也可能是一个挑战。

评论


20年前,我所有的代码都保存在一个巨大的文件中。现在有成千上万的小文件和测试文件。这是有充分的理由的,它反映了20多年的软件开发(一般的生态系统,而不是我的知识)。 Waaay太久了,无法发表评论。

–迈克尔·杜兰特(Michael Durrant)
2015年8月1日在10:44



啊,古老的瀑布式方法甚至在编码开始之前就编写了一个单一的,全部包含的,不可变的真相,这甚至使得在实现上不可能偏离所说的真相。

– jwenting
15年8月2日在12:39

@jwenting:您不必走那么远。但是,对您正在构建的东西有所了解仍然是一件好事。

–罗伯特·哈维(Robert Harvey)
2015年8月3日在2:04

当然,没有对如何正确地分解规则以及在何处打破规则的警告,您很快就会拥有一个过时的文件或磨刀石。 “我需要增加一门新课;吃时间的巨兽Documanto!”

–deworde
15年8月3日,9:49

@deworde:我读这句话是“太懒于维护文档”。

–罗伯特·哈维(Robert Harvey)
2015年8月3日14:16

#5 楼

如果代码库很大,那么我将尝试提供一个设计文档,其中列出了其设计和实现的关键要素。这里的目的不是要详细说明所使用的任何类,而是要提供编码的关键和进入设计的思想。它为系统,其组件及其应用提供了一个总体上下文。

设计文档中要包括的内容是: >逻辑代码结构
数据流
使用的关键模式及其使用的动机
代码源结构
如何构建它(这提供了对隐式依赖关系和物理代码源结构的深入了解)

接着,应适当完成有关类和函数/方法的文档。特别是公共API;应该清楚每种情况下的所有条件;


前提条件
效果
不变式
异常条件(抛出)


评论


+1比描述每个类要好,因为它会比整体设计更快地过时。

–罗德岛
15年8月10日在18:21

#6 楼

我发现使新开发人员更容易理解代码库的最重要规则是完美协议,这很昂贵。在工作中学习。我认为程序员的笔记是一个很好的开始,但是我会走得更远。尝试编写新的代码,如果重新使用它们,它们将使开发人员能够实时确定自己在做什么,而不是要求他们先学习再做。对于您所知的情况,断言之类的小事情永远都不会发生,而解释断言为何有效的注释则大有帮助。如果您做错了任何事情,编写代码也会正常失败,而不是进行段错误。

评论


我的规则是评论应该是关于为什么而不是如何。该代码描述了HOW。

–user11393
15年8月4日在16:41

#7 楼

我看过带有文档的大型类,并且在阅读了文档之后,我不知道该类应该做什么,以及为什么有人会使用它!同时,我需要一些功能,并且我绝对确定必须有一个类来处理它,并且在任何地方都找不到它-因为没有文档将我从我需要的知识引导到该类。正在做。

因此,我在文档中想要的第一件事就是一句话,一个类做什么,以及为什么要使用它。原始问题中的评论在这方面做得很好。阅读这些注释后,如果我有一个由于无法解释其提供的值而无法正常工作的操纵杆,我将知道要检查的代码。

#8 楼

与@meriton所说的类似,将代码分解为单独的组件。更好的是,将代码库分解为单独的程序包(JAR,Gem,Eggs等),以使组件的分离更加清晰。如果存在错误,则开发人员仅需要找到该错误所在的包,并且(希望)仅将其修复。更不用说,单元测试更容易,并且您可以利用依赖管理。

另一种解决方案:缩小代码库。代码越少,越容易理解。重构出未使用或重复的代码。使用声明式编程技术。当然,这很费力,而且通常是不可能或不实际的。但这是一个值得的目标。正如杰夫·阿特伍德(Jeff Atwood)所说:最好的代码根本就没有代码

#9 楼

对于复杂的系统,不仅要记录每个文件,还要记录它们的交互作用和层次结构,以及程序的结构方式和原因,这是值得的。例如,游戏引擎通常非常复杂,很难实现。经过一百层抽象后,决定什么叫什么。可能值得创建一个类似“ Architecture.txt”的文件来解释这种代码的结构以及原因,以及为什么那里没有毫无意义的抽象层。

#10 楼

这可能部分是因为单个程序员很难编写它,因为每个人都只能理解他们的项目部分。

有时您可以从项目经理的注释中获取此信息,但这仅是您将获得的,因为他们很少会以此格式重写其注释。

评论


如果您查看github,则会在README.md文件中找到很多具有这种注释的项目。在一般情况下,它已成为git文化的一部分,尤其是对于javascript项目,对于大多数人而言,它们将不使用没有此类高级文档的库。因此,“没有程序员会写”是不正确的,因为您只需要查看jQuery或socket.io之类的东西,然后找到编写此类内容的程序员即可。 README文件不准确也会生成错误报告,这也已成为一种文化。

–slebetman
15年8月1日在9:41

这似乎并不能回答这个问题,该问题是在寻找为什么建议的文档样式行不通的原因,以及文档标准。

–user52889
15年8月1日在10:57

如果您有一个由一组产品开发人员组成的程序员,并且每个程序员仅了解他们所使用的特定代码,那么不仅您的团队由于一种荒唐的总线因素而无法正常工作,而且还对代码质量提出了质疑。如何在不了解同一系统中其余代码的情况下将代码集成到产品中?

–轨道轻赛
15年8月1日在15:03