教你写好代码注释

article/2025/10/27 0:34:05

前言

相信大家都会遇到这种情况:一周前自己写的代码,现在再拿出来看,发现读不懂了,“ 这代码是我写的???”。这时候,代码注释就可以发挥它的作用了——提高晦涩难懂的代码的可读性;注释可以起到隐藏代码复杂细节的作用,比如接口注释可以帮助开发者在没有阅读代码的情况下快速了解该接口的功能和用法;如果写的好,注释还可以改善系统的设计

既然注释这么多好处,为什么我们程序员还是不愿意写注释?

“代码都写不完了,哪有时间写注释,以后再补吧“

时间不够论。这是最常见的原因,在交付速度飞快的今天,“代码写不完”是一个再常见不过的情况了,但写注释真的会导致需求延迟吗?绝不!相对于写一个接口的实现,写接口注释的时间可能只需要花费前者的5%。但不写注释,后面使用接口的人必须要多花费**50%**的时间去读懂代码!而且对于大部分程序员而言,“以后再补“大概要到2910年才能落实。

“好的代码就是最好的注释,我的代码可读性很好,没必要写注释”

好代码胜过注释论。不少程序员认为,好的代码就是最好的注释,只要代码可读性好,注释就可以省去。然而一个软件系统很多信息是无法通过代码呈现出来的,比如系统的设计思路、函数执行的预置条件等等。此外,代码可读性也不是绝对的,对于一个没有使用过Java 8 的 Lambda表达式的开发者而言,通篇的箭头“->“简直就是一场噩梦。

”过期的注释容易误导人“

过期注释论。不可否认,过期的注释很容易误导读者,但是这并不能成为否认注释的借口。除非是重大的重构或重写,对注释进行大改动的情况很少出现。通常,在更改代码之后,只需花费极少的时间去更新注释,就可以避免过期注释这种情况了。

注释的分类

注释大致可以分成四类:接口注释、数据成员注释、实现注释和模块依赖注释。

接口注释

平时我们所说的接口,通常指的是一个类(包括interface、class、enum)和方法。对类而言,接口注释主要描述该类提供的功能;对方法而言,除了描述方法功能之外,方法的入参和返回值都要进行说明。当然,使用类/方法的一些预置条件和副作用等信息都需要在接口注释中提到。

典型的接口注释(选自JDK 1.8中的String类)

数据成员注释

数据成员注释和接口注释在大多数情况下都是必须的,这对于让读者快速读懂代码有很大的帮助。数据成员包括类的普通成员变量和静态成员变量,数据成员注释除了描述数据成员的本身用途之外,成员的默认值、副作用等信息都需要提及。

典型的数据成员注释(选自JDK 1.8中的String类)

实现注释

对于一段代码,如果无法一眼就看出其含义而需要深入分析其实现才能读懂,就需要添加实现注释对这段代码的含义进行说明。代码的实现注释通常不是必须的,如果一段代码每一行都需要注释,那就要重新审视一下这段代码的设计是否有合理了。此外,实现注释描述还需要描述一些代码无法体现,但是对于读者了解这段代码很有帮助的信息,比如代码的设计思路等。

典型的实现注释(选自JDK 1.8中的String类)

模块依赖注释

模块依赖注释相对少见一些,主要描述两个相互依赖的模块的一些依赖信息,因为它并不属于单独某个模块,所以在哪里写这个注释需要认真衡量一下。实在找不到好的位置时,可以写一个类似README的文件,专门用于描述模块之间的依赖关系。

典型的模块依赖注释(选自《A Philosophy of Software Design》中的例子)

如何写好代码注释

利用好注释模板

注释模板为注释写作提供了极大的便利,我们常用的开发工具如IDEA、VS Code都对注释模板有很好的支持。在配置好注释模板之后(一般情况下默认模板即可),只需简单的操作,就能生成模板,我们只需往模板里填上内容即可。对于方法的接口注释,注释模板尤为方便,方法的入参和返回值标识注释模板都已经提供好。

IntelliJ IDEA默认的注释模板

不要重复代码

注释与代码重复是开发者最容易犯的一个错误,这也是很多开发者认为注释是冗余的原因。确实,对于那些通过读代码可以很容易就推断出来的信息,注释就是多余的,更甚者,出现过期注释还容易误导读者。

典型的重复代码的注释(选自《A Philosophy of Software Design》中的例子)

某些程序员喜欢在注释中使用代码中的变量名或其中的单词,这种情况也是注释重复代码的一种体现。像下面的这个例子,注释完全就是冗余的,可以猜测开发者纯粹是为了注释而注释。

使用代码变量名的注释

注释也要分层

在进行系统设计时,我们常常会采用分层架构,每一层负责不同功能。系统的顶层往往会更抽象一点,为功能调用者隐藏了很多细节(high-level);底层往往会更细节一点,实现系统的具体功能(low-level)。在进行注释写作时,我们也要学会对注释进行分层。high-level的注释要提供比代码更抽象的信息,比如代码的设计思路;low-level的注释要提供比代码更细节的信息,比如表示一个范围的两个参数是左闭右开还是左闭右闭;我们需要避免写出与代码同一level的注释,因为这往往就是上一节所提到的注释重复代码

low-level注释写作指南

对于需要通过阅读这一段代码才能获取的信息,就适合以low-level注释写在这段代码前面,一些常见的例子有:

  • 变量的单位是什么?
  • 表示范围的一组参数是左闭右开还是左闭右闭?
  • 某个变量为null时代表什么含义?
  • 某个资源应该由谁来负责释放,接口调用者还是接口提供者?

low-level注释不能太过抽象,否则就失去了其应有的作用。

太过抽象的low-level(选自《A Philosophy of Software Design》中的例子)

典型的low-level注释(选自《A Philosophy of Software Design》中的例子)

high-level注释写作指南

high-level注释的作用是隐藏具体实现细节,快速让读者对整一段代码有一个全局的了解。high-level注释除了描述对代码进行抽象的概括(What)之外,还经常描述代码的设计思路(Why),这有助于帮助读者更容易、深入地了解整个系统。high-level注释不应该描述具体代码实现的信息,更不能犯注释重复代码的错误。在写high-level注释之前,先问一下自己:

  • 这段代码要做什么事情?
  • 这段代码最核心的功能是什么?
  • 怎样才能以最简单的描述表达这段代码的核心功能?

太过细节的high-level注释(选自《A Philosophy of Software Design》中的例子)

典型的high-level注释(选自《A Philosophy of Software Design》中的例子)

规范接口注释

接口注释是用的最多的一种注释,它可以让读者快速了解整个模块的功能并知道如何使用该接口,而不必花费大量时间去阅读源码。

对于一个的接口注释,其通常是high-level的注释,主要描述这个类提供的一些功能;

对于一个方法的接口注释,则同时需要包括high-level和low-level的注释,常见的有以下几点:

  • 整个方法提供的主要功能
  • 方法的所有参数和返回值含义
  • 调用该方法的副作用(比如改变了系统的某个状态)
  • 该方法可能抛出的所有异常
  • 调用该方法的预置条件(比如调用该方法前,系统必须处于某个状态)

实现注释描述what、why,而不是how

写实现注释时需要记住的最重要的一点就是,描述代码是做什么的(what)和为什么这么做(why),而不是描述怎么做(how)。因为实现代码本身就是how,如果还添加描述how的注释,那就犯了“注释重复代码”的错误了。

典型的描写how的实现注释(选自《A Philosophy of Software Design》中的例子)

典型的描写what的实现注释(选自《A Philosophy of Software Design》中的例子)

实现注释通常不是必须的,对于一些简短的、功能单一的函数,一个好的函数命名即可替代实现注释。

总结

注释是软件开发过程中的性价比极高的一个工具,它只需要花费20%的时间,即可获取80%的价值。代码注释最重要的作用就是让读者可以在不读源码的情况下,快速了解一段代码的主要功能。注释的作用还远远不止这些,John Ousterhout在《A Philosophy of Software Design》一书中提到,写注释最好的时机是在写代码之前。这样,注释就相当于一种设计工具:在编码前通过注释描述这段代码的功能,然后在通过编码实现这个功能,如果这个过程有偏差,则再调整注释。写注释时要切记两点,不要重复代码更新代码后也要更新注释!前者可以减少冗余的注释,后者则可以避免因为过期的注释而误导读者。

当然,注释也不是越多越好,如果一个系统写的注释太多,很有可能就是该系统设计得过于复杂,只能通过注释来帮助读者理解整个系统。

总而言之,学会怎么写好代码注释,是一个程序员的必备技能,这即是为了开发团队的其他成员,也是为了未来的自己。


http://chatgpt.dhexx.cn/article/sNA5IcS9.shtml

相关文章

关于代码的注释的几种方法

注释就是对代码的解释和说明,其目的是让人们能够更加轻松地了解代码。注释是编写程序时,写程序的人给一个语句、程序段、函数等的解释或提示,能提高程序代码的可读性。注释只是为了提高可读性,不会被计算机编译。 注释一般分为行注…

C++设计模式之观察者模式和发布订阅模式

在软件工程中,设计模式(Design Pattern)是对软件设计普遍存在(反复出现)的各种问题,锁提出的解决防范。根据模式的目的来划分的话,GoF(Gang of Four) 设计模式可以分为以…

Redis发布订阅模式实现原理

前言 发布订阅系统在我们日常的工作中经常会使用到,这种场景大部分情况我们都是使用消息队列,常用的消息队列有 Kafka,RocketMQ,RabbitMQ,每一种消息队列都有其特性,很多时候我们可能不需要独立部署相应的消…

RabbitMQ入门案例之发布订阅模式

前言 本文章主要介绍RabbitMQ的发布订阅模式,该模式下,消息为广播形式,一经发布则会进入交换机绑定的队列中,详细介绍可以阅读官方文档。 官网文档地址:https://rabbitmq.com/getstarted.html 什么是发布与订阅模式 …

浅谈JS发布订阅模式

🏆分享博主自用牛客网🏆:一个非常全面的面试刷题求职网站,真的超级好用🍬 文章目录 前言一、发布订阅模式是什么?二、使用步骤1.创建调度中心2.实际操作3. React中的应用 总结 前言 在使用前端各大框架时&…

React 中的发布订阅模式

1、react 通信 react的数据流是单向的, react 通信有以下几种方式: 单向数据流:指当前组件的 state 以 props 的形式流动时只能流向组件树中比自己层级更低的组件 父向子通信:父组件提供state,并且内部设置好数据,子组…

深入Vue原理_全面剖析发布订阅模式

文章目录 发布订阅模式优化优化思路思考理解发布订阅模式(自定义事件)收集更新函数触发更新函数6.5 总结 总结写在最后本期推荐 欢迎各位小伙伴们! 为大家推荐一款刷题神奇哦 点击链接访问牛客网 各大互联网大厂面试真题。从基础到入阶乃至原理刨析类面试题 应有尽有…

观察者模式VS发布订阅模式区别

观察者模式VS发布订阅模式区别 观察者模式:订阅者收集函数,发布者循环调用 发布订阅:收集发布单独给一个中介 对比 以结构来分辨模式,发布订阅模式相比观察者模式多了一个调度中心; 以意图来分辨模式,都…

RabbitMQ:发布订阅模式

✨ RabbitMQ:发布订阅模式 1.订阅模式基本介绍2.交换机3.发布订阅模式3.1基本介绍3.2生产者3.3消费者3.4测试 📃个人主页:不断前进的皮卡丘 🌞博客描述:梦想也许遥不可及,但重要的是追梦的过程,用博客记录自己的成长,记…

JavaScript设计模式:四、发布订阅模式

JavaScript设计模式:四、发布订阅模式 文章目录 JavaScript设计模式:四、发布订阅模式一、概述1. 观察者模式2. 发布订阅模式3. 观察者模式是不是发布订阅模式 一、概述 观察者模式: 观察者(Observer)直接订阅&#x…

发布订阅模式理解

发布订阅模式理解 1.发布-订阅模式 发布订阅模式是一种一对多的对象对应关系,多个观察者同时监听某一个对象,当该对象发生改变时,就会执行一个发布事件,这个发布事件会通知所有的事件订阅者,事件订阅者根据得到的数据…

JS观察者模式和发布订阅模式

观察者模式 观察者模式在前端工程中是很常见的设计模式,因为前端交互中充斥着大量多控件联动的交互,当参与联动的组件数量比较多或者组件数量可能变化的时候,代码就会变得难以维护。但是如果我们写代码时遵循了观察者模式的设计,…

redis发布订阅模式详解

文章目录 写在前面发布订阅的使用SUBSCRIBE命令PUBLISH命令注意发布、订阅客户端启动顺序! PUBSUB命令PUNSUBSCRIBE命令UNSUBSCRIBE命令PSUBSCRIBE命令 总结 写在前面 Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订…

Vue发布订阅模式

简单的来说一下在别人问你这个问题的时候怎么来回答它 前端新人,如有错误求大佬指出~求教💝 情景复现 大佬提问:“你知道Vue发布订阅模式是什么吗?" 我的回答:“发布订阅模式其实是一种对象间一对多的依赖关系&…

观察者模式和发布订阅模式

一、概念 观察者(Observer),又称发布-订阅(Publish-Subscrice),属于23中设计模式之一。 发布订阅模式定义了一种一对多的依赖关系,让多个订阅者对象同时监听某一个主题对象。这个主题对象在自身状态变化时&#xff0c…

C++发布订阅模式

C发布订阅模式 发布订阅模式主要包含三个部分:消息发布、消息订阅者、消息处理中心。与观察者模式相比多出了消息处理中心模块,这样在结构上可以解耦订阅者与发布者,功能上更加的丰富。 观察者模式 结构设计 有一个消息list,主…

Java实现发布订阅模式

什么是发布订阅模式 发布订阅模式是软件开发者很常见的一种设计模式,很多开源库都使用了发布订阅模式,例如RxJava、EventBus、Vue等,所以学习该模式还是很有必要的。 该模式中存在一个或多个发布者,一个或多个订阅者&#xff0c…

设计模式 —— 发布订阅模式

设计模式 —— 发布订阅模式 《工欲善其事,必先利其器》 我在之前有写过一篇关于 《观察者模式》 的文章,大家有兴趣的可以去看看,个人认为那个例子还是挺生动的。(狗头) 不过今天我们要学习的是,发布订阅…

小侃设计模式(十八)-发布订阅模式

1.概述 发布订阅模式又叫观察者模式(Observer Pattern),它是指对象之间一对多的依赖关系,每当那个特定对象改变状态时,所有依赖于它的对象都会得到通知并被自动更新,它是行为型模式的一种。观察者模式内部…

发布-订阅模式

发布-订阅模式 学习知识要善于思考,思考,再思考。 —— 爱因斯在众多设计模式中,可能最常见、最有名的就是发布 - 订阅模式了,本篇我们一起来学习这个模式。 发布 - 订阅模式 (Publish-Subscribe Pattern, pub-sub&a…