曾经我对“一份好的代码里注释至少要占到一半的份量”这样话深信不疑,我也不厌其烦的给每一个函数都加上javadoc,对此,我深感自豪;而对于别人写代码不加注释的“坏习惯”,我深表遗憾。然而当我读完Robert的“注释”一节,我已经懊恼不已,并且我已经开始对我的代码进行审核,再次优化。我已经开始遵守“别给糟糕的代码加注释–重新写吧”这条准则。
也许你是一个好人,会对代码进行不断的优化改进,然而你经常会把注释忽略掉,就如同下面这样:
/** * 集合竞价. * * @param orderFromClient * @return */
private Message callAuction(SelfOrder orderFromClient, long b, JadeInfo jadeInfo) {
方法参数已经改变了,然而javadoc的注释中依然只有一个参数。
我个人已经深深地被Robert影响了,代码才能最忠诚的告诉它在做什么,而不是注释。但是我们很多人,包括在看这本书之前的我,认为写得一手好注释的程序员才是好程序员,当然这不包含那些只会写糟糕代码的人。
我们来比较一下这两种代码:
public void pause() {
if (isNotAction()) {
return;
}
}
/** * 节假日或当天无交易商品,服务器不执行操作 */
private boolean isNotAction() {
if (isHoliday || !hasTradingJade) {
return true;
}
return false;
}
public void pause() {
// 节假日或当天无交易商品,服务器不执行操作
if (isHoliday || !hasTradingJade) {
return ;
}
}
我认为第一种更好,因为节假日以及无交易商品,就说明服务器当日不需要运行,那么用isNotAction来表明会更好。
对意图进行解释
/* * 按照用户id对资金变化量进行排序,从而保证在多线程同时更新资金字段时,不发生死锁 */
@Override
public int compareTo(VarialMoneyUser o) {
return this.getUid().compareTo(o.getUid());
}
这样的注释,我认为还不错,说明了使用compare的意图。
TODO注释
有的时候,我们的需要做一些事情,而我们暂时没有做,那么就可以使用TODO,这样IDE就会管理到这些TODO,当然还有FIXME标记,表明我们有些问题暂时不知道怎么优化、改善。
trade.setDjzj(BigDecimal.valueOf(0));// FIXME 冻结资金待实现
// TODO 计算账户的盈亏,根据风险控制等级,标示次日需要提醒、限制交易、强制平仓的账户
但是需要注意,定期的回头检查,eclipse提供以下图片的功能,你要删除那些无用的TODO
喃喃自语
public void dailyUpdateSystemData() {
// 每日更新时进行一次会员信息更新
AllMembercoes.init();
以上的注释毫无必要。
多余的注释
/** * @Description: 获取指定日期的行情日报 */
public QuotationDailyReport getQuotationReportByDateAndScode(QuotationDailyReport report);
/** * @Title: addQuotationReport * @Description: 添加行情日报 * @param tradeReport * @return */
public int addQuotationReport(QuotationDailyReport tradeReport);
/** * @Title: getLastQuotationReport * @Description: 获取指定商品上一次的行情日报信息 * @param map * @return */
@SuppressWarnings("rawtypes")
public QuotationDailyReport getLastQuotationReport(Map map);
这些注释比没有注释还可怕,其实看方法名称,都知道要做什么,加上注释后反倒浪费时间。
ps:我之前非常喜欢加这种注释,我恨不得在每一个方法上面加上注释,但是自从我明白了,方法名本身就应该代表了方法要做什么以后,我深恶痛绝自己以前荒唐的行为。
误导性注释
这个非常的可怕,很多时候,注释和代码表达的意思完全相反,或者牛头不对马嘴,总之很容易让人迷惑。
// 12点后设置isreload为true,重新加载配置,
private void updateReloadStatusTrue() {
这个注释在本意上应该是非常友好的,提示这个方法是在12点以后执行的,但是我上下文翻看,压根找不到任何12点的信息。
这样会好一点
/** * 设置isreload为true,表明配置服务、商品服务可以重新加载了 */
private void updateReloadStatusTrue() {
reload = true;
ConfigService.isReload = reload;
JadeInfoService.isReload = reload;
}
循规蹈矩的注释
哦,这种注释多发生在方法上,我曾经就非常热衷于这样的注释,现在我才知道其可怕之处。
/** * @Title: updateQuotation * @Description: 修改指定商品的行情信息 * @param quotation */
public void updateQuotation(Quotation quotation) {
this.quotationMapper.updateQuotation(quotation);
}
title、param的注释有两种坏处
日志式注释
以前我们特别喜欢在代码里加上以下这样注释
// start update by maweiqing
// 如果能够接收到消息,说明客户端已经进行操作了,那么就更新session的时间
data = CryptUtil.encrypt(data, SessionManager.getSession(getSession().getSessionId())
.getEncryptKey());
// end update by maweiqing 2015-05-27
看到Robert的建议后,我真的才恍然大悟,这样的代码还要SVN的代码管理器干嘛?SVN在提交的时候自然会让你输入你的修改理由、以及自动显示署名、日期的。
废话注释
// 标识列
private Integer id;
// 用户id
private Integer userId;
// 用户名
private String userName;
这样的注释完全没有必要,你认为有吗?
/** * @return the id */
public Integer getId() {
return id;
}
/** * @param id * the id to set */
public void setId(Integer id) {
this.id = id;
}
还有利用IDE生成的这种bean注释,我真后悔自己当初为什么会这样想,加上这样的注释让自己显得专业吗,显然适得其反。
位置标记
虽然我暂时没有在自己的代码中找到,但是之前我这样做过。
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//aaaaaaaaaaaaaaaaaaaa
注释掉的代码
哦,显然我又中招了,之前我特别喜欢把那些所谓还有作用的代码留在代码里,及时压根就是错误的。但是自从我看到Jeff的博客后,我就开始删掉了那些注释掉的代码,今天再看到Robert的文章,感觉这些伟大的程序员他们都会有这样相似的真理。
如果你的代码中还有这样的注释,请尽快删掉吧,危害太大。
总结:我觉得Robert的文章越来越深入的影响着我,让我改变了很多陋习。