猿 份
来源:程序员的那些事(ID:iProgrammer)
请不要尝试简化这些代码!
Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。Kubernetes 简称 K8s,用「8」替代 K 和 s 之间的 8 个字母「ubernete」。
K8s 的 pv_controller.go 源码大约 1700 行(含注释),其中包括:230+ 个 if 语句、30 个 else 语句、5 个 else if 语句嵌套在一起。
https://github.com/kubernetes/kubernetes/blob/ec2e767e59395376fa191d7c56a74f53936b7653/pkg/controller/volume/persistentvolume/pv_controller.go#L323
乍一看,这代码违背了 KISS (Keep it simple, stupid)原则。
但是,K8s 的工程师们在注释中用大写英文标注:「请不要尝试简化这些代码!」并且还写了两遍。
为啥强调两遍?K8s 他们在注释中特意解释了。大意如下:
这个控制器故意以一种非常冗长的风格编写。你会发现:
1、每个 if 语句都有一个匹配的 else 语句(检查客户端 API 调用的简单错误除外);
2、有很多被显式地注释的东西;
我们把这种风格叫做“航天飞机风格”。航天飞机的风格意味着,要确保每个分支和条件都得到考虑和说明。NASA 为航天飞机等应用程序编写的代码也是如此。
最初,这个控制器的工作被分成三个控制器。控制器是努力简化 PV 子系统的成果。在此过程中,我们要确保在代码中处理和解释了每一个条件,即使这会导致无 op 代码分支。
因此,控制器代码可能看起来过于冗长、注释过多和“分支”。但是,这里记录了大量的业务知识和上下文,以便确保未来的维护者能够正确地推断绑定行为的复杂性。因此,对这个文件的修改,应该保留并增加航天飞机的风格。
程序员们的看法
12 月 8 日,这段特别的源码注释在 Hacker News 上引发程序员们的热议。「程序员的那些事」摘译一些几位国外程序员的评论:
Klathmon的观点:
我超喜欢!它就是软件开发的「爵士乐」。虽然它打破所有的「规则」,但它目的明确,比遵循「规则」的结果还要做的好。
我第一眼看的时候,感觉头都要炸了。源码文件太大了,有太多的分支和嵌套的 if 语句,有很多只是描述一行或几行是做什么的毫无意义的注释。而且注释中还有很多「逻辑」,相比实际代码,这些「逻辑」这可能很快过时或出错。
然而!它们这种方式更利于维护和管理代码,不需要把「逻辑」部分拆分成数十或数百个文件。它已包含了要在该文件中做的大量固有的复杂工作,并且注释写的又好又详细,所以确保了以后有任何改动,注释都能轻松地随之更新。
nickharr的观点:
在用多种编程语言编写、查看、注释和评审代码方面,我有 25 年的经验,抛开编程「风格」如何如何,这都是很值得一看的东西。
退一步说,虽然我们都可以忽略代码注释,但是优秀的代码注释可以极大地提高生产力——对个人、团队乃至企业都是如此。注释可以帮助存储库知识(这往往是当前和以前的团队/个人之间很容易丢失的东西),不应该将其误认为查看代码的人的智慧……
我花了太多的时间,试图对没有注释或解释的代码进行反向工程。有时,经验丰富的程序员/开发人员会走一些捷径(经验不足的开发者无法理解)。他们会根据自身的语言/领域知识,来压缩程序和函数,但没有解释……
我认为,注释应该:告知、教育、概括和帮助他人,来理解开发者在巨大压力下时写出的复杂程序或函数。
有些人认为,好的代码不需要解释。这个观点,在某种程度上是对的,但并不是放之四海而皆准。代码有时会变得复杂、笨拙、就像意大利面条一样,难以理解。
我一直在努力教经验不足的开发者如何用幽默的方式(如果可能的话)写良好、有效的注释。它能让我们快速理解代码,欣赏前人的努力,笑对复杂挑战。
就我个人而言,我并不真正关心代码/注释比率——这完全是在转移人们的注意力。有时,代码注释可能比代码本身更有价值。在其他时候,注释只是帮助你完成工作。快速、高效、没有问题,就是优秀的代码。
@memories_on:if必须加个对应的else有时非常有用 在你要改动逻辑判断的组合时就更有用了
@PreciselyPrecious:与KISS刚好相反
@柳烟堆雪:这不是什么代码风格,而是当时做pv controller时 edge case实在太多,为了让后续开发者能明白怎么回事所以要故意往啰嗦里写。kubernetes 项目开发者近两千,这种作法和修饰其实能找到不少的。
@刻板的眼睛:《代码之美》中有看到,在一些情况下是可以放弃一些编码规则的,只要好处够多
@D2942D4EADA2C788C171BC53B3A68D:这类编程工作的核心应该是逻辑表达清晰且代码量尽可能少以减少犯错概率。这恰恰是代码生成器最擅长的地方,除了固定的优化和表达规则,不会自作聪明对逻辑进行等效裁剪。可以预见领域语言会是这类领域绝对的霸主。