关于注释代码,"硬性规则"是什么?
我看到了其他问题,但是我仍然不满意本主题的覆盖方式。
我想提取一个分散的事物列表,以便在代码检查时检查注释。
我相信人们会说只会互相抵消的事情。但是,也许我们可以为每个营地建立一份清单。对于那些根本不评论的人,列表将很短:)
解决方案
如果注释已过期(与代码不匹配),请删除或者更新。切勿在评论中留下不正确的地方。
Documentation is like sex; when it's good, it's very, very good, and when it's bad, it's better than nothing
尽可能编写易于解释的可读代码。每当我们必须编写过于复杂而无法一目了然的代码时,请添加注释。还添加注释以描述我们编写的代码背后的业务目的,以使其在将来维护/重构时更加容易。
在实施RFC或者其他协议规范时,请注释状态机/事件处理程序/等以及它们所对应的规范部分。请确保列出规格的版本或者日期,以防日后对其进行修订。
我写了一篇关于差评的文章。享受 :)
代码中产生了多么糟糕的注释
我们编写的注释可能揭示了代码的质量。我无数次删除了代码中的注释,以更好,更清晰的代码替换它们。为此,我遵循一些反注释规则:
- 如果注释仅说明了一行代码,则应让该行代码说明一切,或者将其拆分为更简单的组件。
- 如果注释解释了一个函数中的代码块,则可能应该解释一个新函数。
对于两个不同的上下文,这些规则实际上是重复的。
我遵循的其他更常规的规则是:
- 使用动态类型的语言时,请记录重要函数对其参数的期望值,以及调用者对返回值的期望值。重要的功能是那些将具有非本地调用者的功能。
- 当逻辑由另一个组件的行为决定时,最好记录一下我们对该组件的理解和期望。
- 我用元注释来评论公共或者受保护的函数,如果我记得的话,通常会打私有函数。
- 我评论为什么存在任何足够复杂的代码块(判断调用)。为什么是重要的部分。
- 如果我编写的代码不是最佳选择,我会发表评论,因为我无法找到更聪明的方法,或者我知道以后会进行重构,所以我将其留给了我。
- 我评论是为了提醒自己或者其他人缺少功能或者代码中不存在的即将到来的需求代码(TODO等)。
- 我评论解释与类或者代码块相关的复杂业务规则。众所周知,我写了几段文字以确保下一个家伙/加拉知道我为什么写一百行课。
仅前同步码;说明班级的"单一职责",任何注释或者评论,并更改日志。对于方法,如果有任何方法需要大量注释,则是时候进行重构了。
关于注释,我有一个简单的规则:代码应说明我们正在做的事情;评论应说明我们为何这么做。
这样,我确保继承我代码的人都能理解代码的意图。
我记录了一个类中的每个类,每个函数,每个变量。简单的DocBlocks是前进的方向。
我通常会为自动API文档编写更多这些文档块,而不是其他任何东西。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
例如,我的一个PHP类的第一部分
/** * Class to clean variables * * @package Majyk * @author Martin Meredith <[email protected]> * @licence GPL (v2 or later) * @copyright Copyright (c) 2008 Martin Meredith <[email protected]> * @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");
而且,如果不是自我解释,为什么某件事以某种方式起作用,我将对此进行评论
在编写注释时,停下来,反思并问自己是否可以更改代码,以便不需要注释。我们可以更改一些变量,类或者方法名称以使情况更清楚吗?某些"断言"或者其他错误检查是否可以将意图或者期望整理出来?我们能否将一长段代码拆分为名称明确的方法或者函数?注释通常反映出我们无法清晰地编写(a-hem,代码)。用计算机语言清楚地写代码并不总是那么容易,但是要花一些时间尝试一下……因为代码永远不会说谎。
P.S.我们在"硬性规则"周围使用引号的事实很明显。未执行的规则不是"硬性规则",唯一执行的规则在代码中。
我通常在编写方法之前先对其进行评论。对于该函数中需要执行的每个步骤,我将写一两行注释,然后在注释之间编写代码。完成后,代码已被注释。
最好的一点是,在我编写代码之前先对其进行注释,因此注释中没有关于先前知识的不合理假设;我自己编写代码时对代码一无所知。这意味着它们往往应该很容易理解。
没有硬性规定硬性规定会导致教条,当人们不够聪明以至无法自己思考时,人们通常会遵循教条。
我遵循的准则:
1 /注释告诉正在执行的操作,代码告诉正在执行的操作,请不要重复工作。
2 /注释应指代代码块,而不是每一行。其中包括说明整个文件,整个功能或者仅是一个复杂代码段的注释。
3 /如果我认为我会在一年后回来并且不了解代码/注释组合,那么我的评论还不够好。
我在一段代码中添加了1条注释,以总结我在做什么。这可以帮助正在寻找特定功能或者代码部分的人员。
我评论任何乍一看都无法弄清楚的复杂算法或者过程。
我在我的代码上签名。
注释的好规则:如果我们正在阅读代码以尝试找出问题,而某处的注释会给我们答案,则在知道答案时将其放在此处。
只花那时间调查一次。
最终,当我们编写离开指南所需的位置以及足够明显以至于不能单独站立时,我们将知道这些位置。在此之前,我们将花时间浏览代码,以弄清楚为什么要做某事:)
我唯一可以保证发表评论的地方:TODO部分。在代码中,这是跟踪需要重做的东西的最佳位置。
我在代码的开头创建了一个注释块,列出了程序的用途,程序的创建日期,任何许可证/版权信息(例如GPL)以及版本历史记录。
如果不清楚为什么要导入,我经常会评论我的导入,尤其是在整个程序似乎不需要导入的情况下。
我在每个类,方法或者函数中添加一个文档字符串,描述该块的用途以及我认为必要的任何其他信息。
我通常会为相关的部分划界线,例如小部件的创建,变量等。由于我在编程环境中使用了SPE,因此它会自动突出显示这些部分,从而使导航更加容易。
我在编写代码时将TODO注释添加为提醒。这是提醒自己验证代码可以正常工作后对其进行重构的好方法。
最后,我对个别行进行注释,这些行可能需要澄清,或者在将来或者其他程序员中需要一些元数据。
就个人而言,我讨厌看代码并试图弄清楚它应该做什么。如果有人可以写一个简单的句子来解释它,那么生活会更轻松。在我的书中,自我记录代码是用词不当。
我专注于为什么。因为什么通常很容易阅读。
TODO也很棒,它们可以节省大量时间。
我记录了接口(例如文件格式)。
我认为,TODO / TBD / FIXME等可以在当前正在处理的代码中使用,但是当我们看到五年来没有被触及并且充满了代码的代码时,我们会意识到这是一个相当不错的选择确保问题得到解决的糟糕方法。简而言之,注释中的TODO注释倾向于保留在该位置。如果我们需要在某些时候修复某些问题,最好使用Bugtracker。
Hudson(CI服务器)有一个很棒的插件,可以扫描TODO并记录代码中有多少个。如果阈值太多,我们甚至可以设置阈值,使构建被分类为不稳定。
关于注释,我最喜欢的经验法则是:如果代码和注释不一致,则可能都是不正确的
在检查标题文档(或者方法声明之前的任何块)时要检查的一个非常重要的事情是,指令和注意事项很容易发现。
指令是影响客户端的任何"执行"或者"不执行"指令:请勿从UI线程调用,请勿在性能关键代码中使用,在Y之前调用X,在使用后释放返回值等。
注意事项可能会令人讨厌:剩余的操作项,已知的假设和限制等。
当我们专注于正在编写和检查的方法时,我们将看到所有内容。当程序员在一个小时内使用方法和其他三十个方法时,我们将无法完全阅读。如果我们有兴趣,我可以向我们发送有关此方面的研究数据。