低级程序员才喜欢写注释!
Hollis
共 4805字,需浏览 10分钟
· 2020-07-29
作者 | Tameem Iftikhar
译者 | 平川
策划 | Tina
我并不是提倡不写代码注释,只是建议不要过于依赖注释,这样可以使代码更干净、更有表现力,这也能提高开发人员的水平。我自己也在寻求编写更简洁的代码,我尽力不编写糟糕的注释,并在可能时重构代码。 本文最初发布于 Level Up Coding 官方博客,经原作者授权由 InfoQ 中文站翻译并分享。这篇文章的标题可能会让你情绪激动,但请先耐心听我说完。在适当的位置写下适当的注释可能非常有用,但是没有什么比无用的注释更让代码混乱了。在某些情况下,我敢说,注释可以弥补我们在代码中没有完全表达出来的意思。因此,写注释不值得赞美,而是应该停下来问问自己,是否有更好的方式可以用代码来表达自己。带有少量注释的清晰而富于表现力的代码,要比带有大量注释的混乱而复杂的代码好得多。如果你已经把代码弄得一团糟,不要花时间写注释来解释,而是要花时间梳理代码。如果每次写注释的时候,你都冥思苦想,觉得自己的表达能力不足,那么最终你就会写出简洁明了的代码,完全没有必要写注释。鼓励自己用代码表达。为什么对注释如此不屑?因为它们会说谎,还会把代码弄得乱七八糟。虽说并非总是如此,也并非有意如此,但却经常如此。糟糕的代码和带有大量注释的代码之间有很高的相关性。注释存在的时间越久就越容易偏离它们所描述的代码——在某些情况下,它们可能是完全错误的。实际上,随着代码库和团队的增长,维护注释成了不可能的事情。
注释不同于《辛德勒的名单》。它们不是“纯善的”。事实上,注释充其量是一种必要的恶。——Robert C.Martin当谈论关于注释的话题时,很重要的一点是,我们要看一下什么是恰当的注释,什么是糟糕的注释,这样我们才能学会写更好的注释,或者完全避免注释。 恰当的注释并不是所有的注释都是不好的——有些注释实际上非常必要。 出于法律目的的注释有时候,你可能需要出于法律目的编写特定的注释,比如开源项目的创作许可。一些现代化的 IDE 和文本编辑器会自动将它们折叠起来,保持工作区的整洁。 魔术表达式如果你有一个复杂的 SQL 或正则表达式,它以神奇的方式做了一些令人兴奋的事,那么请务必注释,以便让读者更容易理解,因为我们都不是 Regex 忍者。
// 匹配电子邮件地址的正则表达式var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;return re.test(String(email).toLowerCase());// 注意:添加一个富于表现力的函数名,注释就变得没有必要了function validateEmail(email) {var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;return re.test(String(email).toLowerCase());}
说明意图在某些情况下,注释有助于解释决策或特定解决方案背后的意图。例如,测试套件中的一条注释告诉我们添加这行代码是为了降低死锁的几率。结果预警用注释说明代码可能会产生严重的或可怕的后果,甚至鼓励这样做。在本例中,开发人员让读者知道,当与回调函数一起使用时,QT 函数不是线程安全的。一般来说,如果一条注释可以避免某个人在编程时陷入绝望,那么它就是有用的。for x in range(1, 500):
# 这是运行多个并行测试时预防死锁的最好方法
time.sleep(0.5)
runTest(x)
TODO 注释"""
许多 Qt 函数都不是线程安全的。如果你使用回调函数,
即使你在所有绘制调用代码的周围都加上锁,你也会遇到段错误,
因为 Qt 的主事件循环仍在运行,并且使用了没加锁的资源。
"""
from multiprocessing.pool import ThreadPool
import sys
from threading import Lock
import time
from PyQt5 import QtCore, QtWidgets
class Task(QtCore.QObject):
updated = QtCore.pyqtSignal(int, int)
...............
...............
这些注释可以帮助我们标记那些我们认为应该做,但是由于某些原因没有做到的事情。它可能会提醒你删除废弃的特性,或者请求其他人查看某个问题。它可能是要求其他人想一个更好的名字,或者是提醒他们根据计划事件做出修改。请记住,TODO 注释不是在系统中留下糟糕代码的借口。本质上,每一行代码都是一种负担——最安全、最快的代码是根本没有代码。现在,大多数优秀的 IDE 都提供了特殊的指令和特性来定位所有的 TODO 注释,所以不太可能漏掉它们。尽管如此,你也不希望代码中到处都是 TODO。所以要经常浏览一下,删除那些你能删除的。 糟糕的注释
这个清单比较长,但在本节中,我们将看到一些更为老生常谈而又随处可见的注释。 明知故问的注释有些注释的意思显而易见,即它们没有增加任何实际的价值,而且大多是噪音。下面是一个开源项目的代码片段,其中包含大量明知故问型的注释,这些注释使代码变得混乱而晦涩。它们所提供的信息并不比代码本身多,而且在某些情况下,阅读注释的时间甚至比阅读代码长。
不清不楚的注释如果你写注释是为了符合公司规定,或者你只是觉得有必要添加一些注释,那么你在注释时就不会进行适当的思考。所以,如果你真的写了一条注释,花点时间让它对阅读它的人有所帮助。/**
* 与该容器相关的集群
*/
protected Cluster cluster = null;
/**
* 人类可读的容器名
*/
protected String name = null;
/**
* 该容器的父容器
*/
protected Container parent = null;
/**
* 创建一个 Loader 配置父类加载器
*/
protected ClassLoader parentClassLoader = null;
在这个例子中,作者想要传达一些有关异常情况的重要信息。但这条注释没能解释清楚我们将退回到什么样的默认状态。如果一条注释要求我们转到另一个模块来找出默认值,那么它就没有发挥应有的作用。 注释掉代码在团队准备好删除代码之前先将其注释掉似乎是一个好主意,但是不要这样做。注释代码是一种弊端,团队中的其他成员不会删除它,因为他们会认为它很重要。我们不是都在使用源码控制吗?所以我们不需要保留旧的代码。我们可以跳到任何我们想要的版本。 噪音注释有些注释毫无意义,纯粹是噪音。时间久了,我们的大脑就会走马观花,我们也会开始跳过那些需要注意的重要注释。考虑一下下面的例子,其中的注释提供了很多价值吗?def load_config():
try:
do_useful_stuff()
except Exception as ex:
# 如有异常,退回到默认状态。
用编写干净代码的决心取代制造噪音的诱惑,你将成为一个更好、更快乐的程序员。 强制性注释这肯定会引起争议。如果规定每个函数都需要一个 Java 文档或 Python docstring,是不是有点傻?大多数时候,类或函数名已经告诉我们注释所描述的内容,它们是多余的。在这个例子中,注释的数量比代码的数量还多——这让我很恼火。-----------------------------
# Exhibit A
# 默认构造函数
def get_todays_date():
return date.today()
-----------------------------
# Exhibit B
# 返回月份的天
# @return: 月份的天
def get_day_of_month()
return day_of_month
使用好的函数名或变量名你可以使用更具表达性的函数和变量名替换注释,从而使代码更简洁。考虑下面的例子,第一个例子中的注释就变得没有必要了,因为有一个更好的函数名可以准确地告诉读者这个函数做了什么。class ComplexNumber:
"""
这是一个用于复数的数学运算类。
属性:
real (int):复数的实部。
imag (int):复数的虚部。
"""
def __init__(self, real, imag):
"""
ComplexNumber 类的构造函数。
参数:
real (int):复数的实部。
imag (int):复数的虚部。
"""
def add(self, num):
"""
该函数用于复数求和。
参数:
num (ComplexNumber):要加的复数。
返回值:
ComplexNumber:包含和的复数。
"""
re = self.real + num.real
im = self.imag + num.imag
return ComplexNumber(re, im)
help(ComplexNumber) # 访问类的 docstring
help(ComplexNumber.add) # 访问方法的 docstring
注释不能弥补代码的糟糕编写注释有一个比较常见的原因是糟糕的代码。我们以前都见过这种情况,在某种程度上,我们自己也犯过这样的错误。我们写一个模块或类,我们心里知道它混乱而无序。我们知道它一团糟。所以我们对自己说,“哦,我最好加下注释!”不!你最好把代码梳理清楚!# 检查日期是否是过去的日期
def check_date(date):
if date < today:
return true
return false
def is_past_date(date):
if date < today:
return true
return false
小 结我并不是提倡不写代码注释,只是建议不要过于依赖注释,这样可以使代码更干净、更有表现力,这也能提高开发人员的水平。我自己也在寻求编写更简洁的代码,我尽力不编写糟糕的注释,并在可能时重构代码——将我的代码从宜家的一幅画变成梵高的作品。所以让我们约法三章,不要写这么多注释。延伸阅读:https://levelup.gitconnected.com/every-time-you-comment-code-youve-already-failed-6fa9773b080f/*
这段代码糟透了。我知道,你知道,每个人都知道。
我们假装什么都没发生,然后继续前进。以后你叫我白痴好了。
*/
有道无术,术可成;有术无道,止于术
欢迎大家关注Java之道公众号
好文章,我在看❤️
评论
阿里的同事,写的代码真 TMD 优雅!
通过这篇文章你将了解到整洁的代码对项目、公司和你的重要性,以及如何书写整洁的代码.通过命名、类、函数、测试这四个章节,使我们的代码变得整洁.1、为什么要保持代码整洁?不整洁的代码随着时间的增加而增加时,生产力会随之降低.导致的结果就是:代码不易扩展或扩展容易引发其他问题程序崩溃加班增加公司成本(加人
Java专栏
1
老爸嘲讽我了,写破代码一年就挣十几万,他在工地带50个工人,一个月光人头费就3万,让我滚回去跟他干!
点击上方 "大数据肌肉猿"关注, 星标一起成长点击下方链接,进入高质量学习交流群今日更新| 1052个转型案例分享-大数据交流群来自:网络,侵删有个网友的父亲是做工程的,天天就嘲笑他,说他天天写着破代码有啥用,一年就拿个十多万的死工资,然后告诉他自己在工地里面带了50个工人,一个月能抽三万
程序源代码
0
网友发问:事业编一年6万,干35年退休挣200万,程序员一年60万,5年就挣300万,事业编再爽能有程序员干五年退休爽?
上一篇:阿里P9被裁,赔偿82w在职场中,我们不可避免地会面临多样的工作机会和选择。然而,如果我们仅将这些不同的工作机会仅以金钱作为衡量标准,那么这种比较就显得过于肤浅和狭隘。一些人可能会通过直接的数学计算来决定哪个职业道路更有利可图,但这种方法忽视了工作的本质、工作量的大小、职业成长的机会,以及经
开发者全社区
0
我想写几个专栏,欢迎大家投票
大家好,我是章北海前段时间更新了一个专栏,阅读和订阅都极不理想,看起来是没有做好调研啊。准备启动新的专栏更新计划了,我有几个选题,看大家更喜欢哪一个呢?欢迎投票,拜谢!
机器学习算法与Python实战
0
只写后台管理的前端要怎么提升自己
大厂技术 高级前端 Node进阶点击上方 程序员成长指北,关注公众号回复1,加入高级Node交流群本人写了五年的后台管理。每次面试前就会头疼,因为写的页面除了表单就是表格。抱怨过苦恼过也后悔过(虽然我现在已经心安理得的摆烂),但是站在现在的时间点
程序员成长指北
1
【第129期】程序员的新宠:三款终端工具,让你告别Xshell!
概述 WindTerm:跨平台的SSH利器 首先介绍的是WindTerm,这是一款使用C语言开发的跨平台SSH客户端。它不仅完全免费,而且没有商业使用的限制。WindTerm支持SSH v2、Telnet、Raw Tcp等协议,而且性能出色,甚至超过了FinalShell和Electerm。功能
前端微服务
0
知乎高问:程序员有必要知道为什么做某个功能吗?
将Python客栈设为“星标⭐”第一时间收到最新资讯前言知乎上有一个提问:程序员有必要知道为什么做某个功能吗?↓↓↓今天,我们就这个话题一起来做个讨论。不知道程序员的你,在接到产品经理提的一个需求后,是习惯马上动手开始撸代码呢?还是会先暂停一下,认真思考一会如下一些问题,比如这个需求产生的背景是什么
Python客栈
0
“渣女”怎样抵抗收入暴跌,去杭州找大厂程序员“接盘”
一位好友给我分享了一张图片,看过之后,我直呼毁三观。不知是哪位大厂员工蒙在鼓里多年,被“渣女”耍的团团转。这也难怪外面传“要嫁就嫁程序员,钱多话少死得早。”敢情成为了某些“心机女”的接盘侠。我不由得想起了曾经轰动一时的“程序员苏享茂事件”,被前妻翟欣欣索要千万跳楼自杀。我在网上详细查了这个案件资料。
Python涨薪研究所
0