我自己,是写注释的拥护者。
网上有一种很流行的观点:
注释应该写为什么(Why),而不是写是什么(What)。
我并不认同。
我认为,在代码本身已经写得比较清晰的前提下,“是什么” 和 “为什么” 都应该写。
尤其是业务代码,写"是什么"这件事,非常重要。
为什么?
因为对于绝大多数业务系统来说,我们阅读代码的时候,真正想知道的第一件事情,并不是某一行代码干了什么。
而是:
这个业务流程到底是怎么走的?
例如下面这样。
public void createOrder() { // 1. 校验下单参数 validate(); // 2. 创建订单 create(); // 3. 根据供应商编码拆单 splitOrder(); // 4. 发布订单已生成事件 publishEvent(); }你会发现,这几行注释没有解释任何实现细节。
它只是告诉你:整个业务流程是什么。
当你第一次接触这段代码时,看一眼注释,就知道整个流程了。
后面再进入每一个方法,看实现细节即可。阅读成本一下子就降低了。
有人可能还会说:方法名不是已经说明了吗?为什么还要写注释?
我的观点是:**方法名当然要起好。**这是最基本的要求。
但是,仅仅依靠方法名,真的够吗?
你今天写完这段代码。两周以后,再回来看看。你还能第一时间回忆起整个业务流程吗?大概率不能。更别说半年以后了。
如果是别人接手你的代码,那理解成本只会更高。而有了上面的四行注释。不用点进去。不用来回跳转。整个流程,一眼就知道。
这种阅读体验,是方法名替代不了的。
当然。我也不是鼓励大家到处写注释。
我最反对的一种写法就是:代码写得一团糟。然后靠几十行注释去解释代码。
例如:
// 获取用户 User user = getUser(); // 判断用户是否为空 if (user == null) { ... }这种注释没有任何价值。因为代码本身已经表达得很清楚了。
真正应该做的,是把代码写好,而不是把注释写多。
所以,在我看来,一份高质量的业务代码,其实只需要写两类注释。
第一类:核心业务流程注释。
告诉阅读者:
第一步干什么。
第二步干什么。
第三步干什么。
整个业务是怎么流转的。
这是阅读业务代码时,价值最高的一类注释。
第二类:解释为什么这么做。
例如:
为什么这里不能直接查数据库?
为什么这里一定要加锁?
为什么这里用了缓存,而不是实时计算?
为什么这里不能合并两个事务?
这些都是代码本身表达不出来的信息。只有注释才能告诉后来的人。
所以,我一直觉得,关于注释这件事,不应该陷入只写 Why,不写 What这样的二选一讨论。
对于业务代码来说。
- 流程(What)决定别人能不能快速看懂业务。
- 原因(Why)决定别人敢不敢修改代码。
两者都很重要。
最后总结一下我的观点。
如果代码本身已经写得比较清晰,那么注释只需要覆盖两个场景:
- 核心业务流程,一定要写。
- 关键设计决策和为什么这么做,也一定要写。
除此之外,不需要写太多。
注释不是为了替代代码,而是为了降低阅读成本。
好的代码,加上恰到好处的注释,才是真正容易维护的代码。