我已经看过其他问题,但我仍然对涵盖该主题的方式不满意。
我想在代码检查中提取一个精简的列表来检查注释。
我相信人们会说一些只会互相抵消的话。但是,嘿,也许我们可以为每个营地建立一个清单。对于那些根本不发表评论的人来说,这份名单会很短:)
我已经看过其他问题,但我仍然对涵盖该主题的方式不满意。
我想在代码检查中提取一个精简的列表来检查注释。
我相信人们会说一些只会互相抵消的话。但是,嘿,也许我们可以为每个营地建立一个清单。对于那些根本不发表评论的人来说,这份名单会很短:)
关于评论,我有一个简单的规则:你的代码应该讲述你在做什么的故事;您的评论应该说明您为什么这样做。
这样,我确保任何继承我的代码的人都能够理解代码背后的意图。
如果评论已过期(与代码不匹配),请将其删除或更新。永远不要留下不准确的评论。
文档就像性;当它好时,它非常非常好,当它坏时,总比没有好
编写尽可能不言自明的可读代码。每当您必须编写过于复杂而无法一目了然的代码时,请添加注释。还要添加注释来描述您编写的代码背后的业务目的,以便将来更容易维护/重构它。
你写的评论可以揭示你的代码质量。无数次我删除了代码中的注释,用更好、更清晰的代码替换它们。为此,我遵循一些反评论规则:
这些实际上是针对两种不同上下文重复的相同规则。
我遵循的其他更正常的规则是:
在实现 RFC 或其他协议规范时,用它们对应的规范部分注释状态机/事件处理程序等。确保列出规范的版本或日期,以防以后修订。
我通常在编写方法之前对其进行注释。我将为函数中需要执行的每个步骤写一两行注释,然后在注释之间编写代码。当我完成后,代码已经被注释了。
最重要的是,在我写代码之前,它已经被注释掉了,所以注释中没有对先前知识的不合理假设;我自己在编写代码时对我的代码一无所知。这意味着它们往往很容易理解,因为它们应该是。
没有硬性规则——硬性规则会导致教条,当人们不够聪明而无法独立思考时,他们通常会遵循教条。
我遵循的准则:
1/ 注释说明正在做什么,代码说明它是如何完成的——不要重复你的努力。
2/ 注释应该指向代码块,而不是每一行。这包括解释整个文件、整个函数或只是一段复杂代码的注释。
3/ 如果我认为我会在一年后回来并且不理解代码/评论组合,那么我的评论还不够好。
我写了一篇关于不良评论的完整文章。享受 :)
评论的一个很好的规则:如果你正在阅读代码试图找出一些东西,并且某处的评论会给你答案,当你知道答案时把它放在那里。
只花那时间调查一次。
最终,当你写下你需要留下指导的地方时,你会知道哪些地方足够明显,可以独立存在。在那之前,你会花时间浏览你的代码,试图找出你做某事的原因:)
我专注于为什么。因为什么通常很容易阅读。TODO 也很棒,它们节省了很多时间。
我记录界面(例如文件格式)。
我记录了一个类中的每个类、每个函数、每个变量。简单的 DocBlocks 是前进的方向。
我通常会为自动化 API 文档编写这些 docblocks,而不是其他任何东西......
例如,我的一个 PHP 类的第一部分
/**
* Class to clean variables
*
* @package Majyk
* @author Martin Meredith <martin@sourceguru.net>
* @licence GPL (v2 or later)
* @copyright Copyright (c) 2008 Martin Meredith <martin@sourceguru.net>
* @version 0.1
*/
class Majyk_Filter
{
/**
* Class Constants for Cleaning Types
*/
const Integer = 1;
const PositiveInteger = 2;
const String = 3;
const NoHTML = 4;
const DBEscapeString = 5;
const NotNegativeInteger = 6;
/**
* Do the cleaning
*
* @param integer Type of Cleaning (as defined by constants)
* @param mixed Value to be cleaned
*
* @return mixed Cleaned Variable
*
*/
但是,我有时也会记录重要的代码(来自我的 init.php
// Register the Auto-Loader
spl_autoload_register("majyk_autoload");
// Add an Exception Handler.
set_exception_handler(array('Majyk_ExceptionHandler', 'handle_exception'));
// Turn Errors into Exceptions
set_error_handler(array('Majyk_ExceptionHandler', 'error_to_exception'), E_ALL);
// Add the generic Auto-Loader to the auto-loader stack
spl_autoload_register("spl_autoload");
而且,如果它不能自我解释为什么某事以某种方式做某事,我会评论说
我留下评论的唯一有保证的地方:TODO部分。跟踪需要返工的东西的最佳位置就在代码中。
我在代码的开头创建了一个注释块,列出了程序的用途、创建日期、任何许可证/版权信息(如 GPL)和版本历史。
如果导入的原因不明显,我经常评论我的导入,特别是如果整个程序似乎不需要导入。
我为每个类、方法或函数添加一个文档字符串,描述该块的用途以及我认为必要的任何其他信息。
我通常为相关的部分设置分界线,例如小部件创建、变量等。由于我在我的编程环境中使用 SPE,它会自动突出显示这些部分,使导航更容易。
我在编码时添加 TODO 注释作为提醒。这是提醒自己在验证代码正常工作后重构代码的好方法。
最后,我对可能需要澄清的个别行进行评论,或者在将来为我自己或其他程序员需要一些元数据。
就个人而言,我讨厌查看代码并试图弄清楚它应该做什么。如果有人可以写一个简单的句子来解释它,生活会更轻松。在我的书中,自我记录代码是用词不当。
当您检查头文件(或任何您在方法声明之前调用的块)时要检查的一件非常重要的事情是指令和警告很容易发现。
指令是影响客户端的任何“执行”或“不执行”指令:不要从 UI 线程调用、不要在性能关键代码中使用、在 Y 之前调用 X、在使用后释放返回值等。
警告是任何可能令人讨厌的惊喜:剩余的行动项目、已知的假设和限制等。
当您专注于您正在编写和检查的方法时,您会看到一切。当一个程序员在一小时内使用你的方法和其他 30 个方法时,你不能指望彻底阅读。如果你有兴趣,我可以把这方面的研究数据发给你。
仅前导码;说明班级的单一职责、任何注释或评论以及更改日志。至于方法,如果任何方法需要大量注释,是时候重构了。
当你写评论时,停下来,反思一下,问问自己是否可以改变代码,这样评论就不需要了。您能否更改一些变量、类或方法名称以使事情更清晰?某些assert
s 或其他错误检查是否会记录您的意图或期望?你能把一些长段代码拆分成明确命名的方法或函数吗?评论通常反映了我们无法清楚地编写(a-hem,代码)。用计算机语言写清楚并不总是那么容易,但需要一些时间来尝试......因为代码永远不会说谎。
PS您在“硬规则”周围使用引号的事实说明了这一点。未强制执行的规则不是“硬规则”,唯一强制执行的规则在代码中。
我在一段代码中添加了 1 条评论,总结了我正在做的事情。这有助于寻找特定功能或代码部分的人。
我评论任何乍一看无法弄清楚的复杂算法或过程。
我签署我的代码。
在我看来,TODO/TBD/FIXME 等在当前正在处理的代码中是可以的,但是当你看到 5 年内没有被触及的代码并且充满了它们时,你会意识到它是一个漂亮的确保事情得到解决的糟糕方法。简而言之,评论中的 TODO 注释往往会留在那里。如果您有需要在某个时候修复的东西,最好使用错误跟踪器。
Hudson(CI 服务器)有一个很棒的插件,它可以扫描 TODO 并记录你的代码中有多少。如果构建的数量过多,您甚至可以设置阈值导致构建被分类为不稳定。
关于评论,我最喜欢的经验法则是:如果代码和评论不一致,那么两者都可能不正确
我们在这里写了一篇关于评论的文章(实际上,我已经做过几篇了):http: //agileinaflash.blogspot.com/2009/04/rules-for-commenting.html
这真的很简单:写注释是为了告诉你代码不能做什么。
这导致了一个简单的过程: - 首先写下您想要的任何评论。- 改进代码,使注释变得多余 - 删除现在多余的注释。- 只提交没有多余注释的代码
我正在写一篇 Medium 文章,我将在其中介绍这条规则:当您将更改提交到存储库时,每条评论必须是以下三种类型之一:
TODO
评论。最后一种类型不应该是永久性的。要么事情完成,TODO
评论被删除,要么我们决定任务没有必要,TODO
评论被删除。