《代码整洁之道》笔记(三)注释

注释就像是一把“双刃剑”,什么也比不上放置良好的注释来得有用;同时,什么也不会比乱七八糟的注释更有本事搞乱一个模块,什么也不会比陈旧、提供错误信息的注释更有破坏性。注释的恰当用法是弥补我们在用代码表达意图时遭遇的失败。

1.注释不能美化糟糕的代码

写注释的常见动机之一是糟糕的代码的存在。

带有少量注释的整洁而有表达力的代码,比带有大量注释的零碎而复杂的代码像样的多。与其花时间编写解释你搞出的糟糕的代码的注释,不如花时间清洁那堆糟糕的代码。

2. 用代码来阐述  

有时候,代码本身不足以解释其行为,比如下面两段代码:

代码段1:

// Check to see if the employee is eligible for full benefits
if ((employee.flags & HOURLY_DAY) && 
    (employee.age > 65))

代码段2:

if (employee.isEligibleForFullBenefits())

很显然,代码段2更容易理解,很多时候,只需要创建一个描述与注释所言同一事物的函数即可。

3. 好注释

有些注释是必须的,也是有利的。不过要记住,唯一真正的好注释是你想办法不去写的注释。

(1)法律信息

有时,公司代码规范要求编写与法律有关的注释。这类注释不应是合同或法典,只要有可能,就指向一份标准许可或其他外部文档,而不要把所有条款放到注释中。

(2)提供信息的注释

// format matched kk:mm:ss EEE, MMM dd, yyyy
Pattern timeMatcher = Pattern.compile("\\d*:\\d*:\\d* \\w*, \\w* \\d*, \\d*");

注释说明,该正则表达式意在匹配一个经由SimpleDateFormat.format函数利用特定格式字符串格式化的时间和日期。

这类注释有时管用,但更好的方式是尽量利用函数名称表达信息。  

(3) 对意图的解释

有时,注释不仅提供了有关实现的有用信息,而且还提供了某个决定后面的意图。

(4) 阐释

当参数或者返回值晦涩难懂时,通常,更好的方法是尽量让参数或返回值自身就足够清楚;但如果参数或返回值是某个标准库的一部分,或是你不能修改的代码,帮助阐释其含义的代码就会有用

(5) 警示

有时,用于警示其他程序员会出现某种后果的注释也是有用的。

(6)TODO注释

有时,有理由用//TODO 形式在源代码中放置要做的工作列表。

TODO是一种程序员认为应该做,但由于某些原因目前还没做的工作。它可能是要提醒删除某个不必要的特性,或者要求他人注意某个问题。

(7) 放大

注释可以用来放大某种看起来不合理之物的重要性。

String listItemContent = match.group(3).trim();
// the trim is real important. It removes the starting
// spaces that could cause the item to be recognized 
// as another list
new ListItemWidget(this, listItemContent, this.level + 1);
return buildList(text.substring(match.end()));

4. 坏注释

大多数注释都属此类。通常,坏注释都是糟糕代码的支撑或借口,或者对错误决策的修正,基本上等于程序员自说自话。

(1)喃喃自语

如果只是因为你觉得应该或者因为过程需要就添加注释,那就是无谓之举。

(2)多余的注释

若注释不能比代码本身提供更多的信息,它没有证明代码的意义,也没有给出代码的意图或逻辑,读它并不比读代码更容易。

(3)误导性注释

有时,不精确的注释会有一定的误导“功效”

(4)循规式注释

所谓每个函数都要有Javadoc或每个变量都要有注释的规矩全然是愚蠢可笑的。这类注释突然让代码变得散乱,满口胡言,令人迷惑不解。


/**
 * @param title The title of the CD
 * @param author The author of the CD
 * @param tracks The number of tracks on the CD
 * @param durationInMinutes The duration of the CD in minutes
 */
public void addCD(String title, String author, int tracks, int durationInMinutes) {
    CD cd = new CD();
    cd.title = title;
    cd.author = author;
    cd.tracks = tracks;
    cd.duration = durationInMinutes;
    cdList.add(cd);
}

(5) 日志式注释

有人会在每次编辑代码时,在模块开始处添加一条注释。这类注释就像是一种记录每次修改的日志。

如今,这种冗长的记录只会让模块变得凌乱不堪,应当全部删除。

(6)废话注释

有时,会有完全是废话的注释。它们对于显然之事喋喋不休,毫无新意。

(7)可怕的废话

Javadoc也可能是废话。

/** The name. */
private String name;

/** The version */
private String version;

/** The licenseName */
private String licenseName;

/** The version. */
private String info;

(8)能用函数或变量时就别用注释

(9)标记位置

有时,程序员喜欢在源代码中标记某个特别位置。例如:

// Actions //

把特定函数放在这种标记下面,多数时候实属无理。鸡零狗碎,理当删除——特别是尾部那一长串无用的斜杠。

如果滥用标记,代码就会沉没在背景噪音中,被忽略掉。

(10)括号后面的注释

有时,程序员会在括号后面放置特殊的注释。尽管这对于含有深度嵌套结构的长函数可能有意义,但只会给我们更愿意编写的短小、封装的函数带来混乱。如果你发现自己想标记右括号,其实应该做的是缩短函数。

(11)归属与署名

版本控制系统非常善于记住是谁在何时添加了什么。没必要用小小的签名搞脏代码。

(12)注释掉的代码

注释掉的代码如果无用,请立即删掉,不然其他人对于注释掉的代码无从下手,不知道其重要性,不敢删除。

(13)非本地信息

假如你一定要写注释,请确保它描述了离它最近的代码。别在本地注释的上下文环境中包含出系统级的信息。

下面的例子,除了可怕的冗余之外,还包含了系统级的默认端口信息。但是这个函数完全没控制那个所谓的默认值。假如那个值更改了,无法担保这个注释也会跟着修改。

/**
 * port on which fitnesse would run. Default to <b>8082</b>
 * @param fitnessePort
 */
public void setFitnessePort(int fitnessPort) {
    this.fitnessePort = fitnessePort;
}

(14)信息过多

别在注释中添加有趣的历史性话题或者无关的细节描述。

(15)不明显的联系

注释及其描述的代码之间的联系应该是显而易见。如果你不嫌麻烦要写注释,至少让读者能看着注释和代码,并且理解注释所谈何物。

(16)函数头

短函数不需要太多描述。为只做一件事的短函数取个好名字,通常要比写函数头注释要好。

(17)非公共代码中的Javadoc

Javadoc对于公共API非常有用,但对于不打算做公共用途的代码就令人厌恶了。为系统中的类和函数生成Javadoc页并非总有用。

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值