机器之心报道,参与:刘晓坤、王淑婷、李泽南。

「我曾接手过一个代码,里面是几十个 if else 模块……」对于程序员们来说,遇到这样的事情应该是苦不堪言的——很多人认为这种写法非常难看、分支众多、容易出 bug。最近,网友们在容器管理平台 Kubernetes 的 GitHub 上发现了这样一段代码,其中的 1700 行 if else 语句却让人叹为观止。

为了防止「头铁」群众真的去重构它,在这段代码的开头,有这样一段注释:

不要尝试简化此代码。

请看着它起飞。

这个控制器是故意以非常详细的方式编写的。你会注意到:

1. 每个『if』语句都有一个匹配的『else』(除了客户端 API 调用的简单错误检查)

2. 在这里我们要明确地解释一下

我们把这种代码叫做『航天飞机风格』。航天飞机风格是为了确保每个分支和条件都得到考虑——就像在 NASA 编写航天飞机的航天器应用程序代码一样。

最初,这个控制器的工作被分成了三个控制器来做。该控制器是为简化 PV 子系统付出巨大努力的结果。在这种努力中,很明显我们需要确保在代码中处理和计算每个条件,即使它导致了无操作代码分支。

因此,控制器代码可能看起来过于冗长,有太多注释和「分叉」。但是,这里记录了大量的业务知识和内容,以确保未来的维护者能够正确地推理绑定行为的复杂性。因此,对此文件的更改应保持航天飞机风格。

该文件的 GitHub 地址:github.com/kubernetes/…

1700 行的 if 嵌套语句。

作为流行的开源系统,Kubernetes 常被用于自动容器化应用程序的部署和管理。其开发者称,Kubernetes 拥有 15 年承担 Google 生产工作负载的经验。对于人工智能领域的开发者来说,Kubernetes 可以帮助我们部署深度学习模型(参见:如何使用 Kubernetes 轻松部署深度学习模型)。

航天飞机的风格

听说它是美国航天局 NASA 的代码风格?在 Hackernews 上,众多网友们在通读全文代码后给出了一致好评。

@Klathmon 表示:

我爱死这个了!这简直就是软件开发里的「爵士乐」。它打破了所有的固有「规则」,但目的明确,比按照「规则」来的结果要好得多。

乍一看,你会觉得这个文件太大了,里面充斥着许多分支和嵌套 if 语句,还有很多「无意义的注释」,仅描述周围一行或几行代码是做什么的。注释里还有很多 logic,与实际代码相比,这些 logic 很快就会过时或者出错。

但同时,这样做使得维护和管理代码变得简单多了,因为你不用把 logic 拆分成几十甚至上百个文件。它包含了大量对这个文件需要进行的固有复杂工作,而它的注释做得又好又多,做任何改变都可以轻易让注释一起更新。

@munchbunny 说:

不能更同意了。我日常要处理的代码不是这个级别,但也有低级别的特点,同样也比典型的后端代码更接近 metal,被许多的前端和后端代码调用。如果有「甚至更后端代码」的东西,这就是个不错的例子。如果你忽略了一个细微的差别,一群愤怒的开发人员会在部署代码时冲到你办公桌前,而如果你没有快速修复它,就会出现一群愤怒的顾客。

对于任务关键型代码内部循环中的代码来说,主要的时间成本并不是写代码或者理解代码,而是根据所服务场景的细微差别进行优化,检查更改代码带来的直接影响,然后检查更改的二阶和三阶影响。

当你的代码非常细化,以至于你做的每个改变都有三阶影响时,带有精心注释的代码会更容易维护。因为假如你拼凑了十个不同的文件,需要花费精力弄清正确的路径,就更有可能忽略其中的细微差别。

关于注释

很多网友对于带大量注释的代码表示很有用、不反感,并且那些不带注释的代码会带来很大的麻烦。

@EB66 说:

我完全同意。对于那些不可避免很复杂的代码,我也喜欢这种风格。

我非常喜欢简洁且语句/命名是表达性的代码,但有时候注释是必要的,以便清楚地阐明逻辑或使用案例。表达性代码能直接传达的含义有限。精心设计的注释可以大大地减少其他开发人员在不熟悉的代码基础上所耗费的时间。

关键是要更新注释。没有比不准确的注释更恶心的事了。检查代码时一定要检查修改过的代码行的注释。

@ascar 说:

解释使用案例或目的的过时注释还是比没有注释强。它能给你提供背景信息,比如代码的演变及其目的。

只读注释可能比读没有注释的代码更糟糕,所以一些开发人员反感过时的注释,因此就有了一般化(过于简略)的注释。

注释是关于代码的附加信息,没有事实来源,所以,要同时阅读代码和注释。

@nickharr 说:

我有 25 年以上用多种语言编写、查看、注释和检查代码的经验,所以我会说这的确是一个好东西——不管编程的「风格」(或者广义上来说的语言)如何。

好的代码注释可以对生产力产生巨大的影响——无论是对个人、团队还是企业来说都是如此。它有助于存储知识(当前和之前的团队/个人之间容易丢失的信息)。

我个人花了太多时间对那些没有注释的代码进行逆向工程。有时候,经验丰富的程序员或开发人员会走捷径:压缩程序和函数,这些程序和函数是基于他们明确了解的语言和/或领域,但没有对它们进行注解……

在基本层面上,注释应该告知、教育、概述和帮助他人理解我们写代码时创造的有时很复杂的路径和函数。

有些人认为好的代码不需要注释,某种程度上这是对的,但这一点并不适用于每个代码库。有些代码很复杂、笨拙,就像意大利面,有时甚至难以理解。

我一直努力教经验较少的开发人员以带点幽默(可能的话)的方式作出高效的好注释——让我们能够快速理解代码,欣赏前人所做的努力,并笑对复杂的挑战。

我个人并不真正关心代码和注释的比率。有时,代码注释可能比代码本身更有价值。而有时,它们只是帮助你完成工作;只要快速、高效、没毛病,就是不错的代码。

文件大小

@Klathmon 说:

我从事前端网页应用开发,其中最复杂的问题在于如何实现代码库的快速迭代,大部分情况下都不是实际的业务问题。但尽管「deep functionality and small interfaces」听起来很不错,大多数情况下,导出的仅有少量函数的大型文件是不容易维护的。将所有代码放到同一个文件中,需要你在做出任何修改之前确保透彻地理解它们。

@taneq 说:

他们是有目的地这样做的,为了确保开发人员在修改之前能理解整个文件,因为其功能非常关键,很容易被混淆。此外,将一个逻辑严密的文件分割成小型文件(而不是改写成更小的逻辑模块)只会导致不必要的文件管理问题。

新手的膜拜

@jml7c5 说:

作为一个初学程序员,我非常震惊这竟然不是编程的标准惯例。一般的源文件应该提供语境、主题背景、解释概念的参考资料/博客/书籍指南、关于代码如何匹配程序整体的信息,以及(最重要的)文件中体现的思考过程(即为什么选择这种做法而不是其它,面临的挑战,权衡等等)。

我还是想不通,每一位程序员都需要从零开始学习使用一个代码库。除非肯花费数小时来做测试,想改善一个 non-trivial 的程序是不可能的。致开源开发者:如果你想要让人们对项目做出贡献,这些类型的注释是很基本的,更不要说它们能帮助节省非常多的时间。

@qlk1123 说:

「作为一个初学程序员,我非常震惊这竟然不是编程的标准惯例。」我同意这一点,如果这能成为社区标准,当然会有很多人受益。但是,你不认为一个好的社区文化可以让人们为此保持良好的习惯吗?

我的日常工作是 Linux 内核开发人员。我发现源代码仅仅是「What」部分,注释中应该声明「How/Why」部分。并且如果这些还不能使我搞明白源代码,我会直接电邮作者问更深层次的「Why」部分。大多数情况下信息都是足够的。

模仿需谨慎

Kubernetes 之外,最近另一个因为代码而被热议的程序可能就是在 Steam 上火起来的独立国产游戏《太吾绘卷》了。据好奇的程序员介绍,其早期版本中内含数千个 if 语句。由于游戏主创是中文系出身,随后又投身建筑行业,半路出家写游戏代码——最后居然玩起来没有什么大问题,代码的「糟糕」样式成为了一个梗,为游戏的流行起到了助推作用。

这些著名的案例虽然可以运行,但没有强大的逻辑(运气)是玩不转的。科班出身的程序员们一般就不要模仿了。

参考内容:news.ycombinator.com/item?id=187…  

我的if else代码纯净无暇,一个字也不能简化相关推荐

  1. 程序员:我的if else代码一个字也不能简化!网友好评如潮

    知乎:机器之心报道 「我曾接手过一个代码,里面是几十个 if else 模块--」对于程序员们来说,遇到这样的事情应该是苦不堪言的--很多人认为这种写法非常难看.分支众多.容易出 bug.最近,网友们 ...

  2. 程序员:我的if else代码一个字也不能简化,网友好评如潮

    「我曾接手过一个代码,里面是几十个 if else 模块--」对于程序员们来说,遇到这样的事情应该是苦不堪言的--很多人认为这种写法非常难看.分支众多.容易出 bug.最近,网友们在容器管理平台 Ku ...

  3. java三目运算符简化代码_如何使用传播运算符简化代码

    java三目运算符简化代码 by Matt Granmoe 通过Matt Granmoe 如何使用传播运算符简化代码 (How to simplify your code with the sprea ...

  4. python田字格函数简化代码_[Python]使用生成器来简化代码

    原本只是大概知道生成器是什么,但一直不知道怎么用,或是什么情景下用,后来才发现: 在需要一边读数据一边处理任务时,如果直接为每个任务都写一个函数,那么读数据的部分就要在每个函数都重复一遍 直接将所有任 ...

  5. 机器翻译学习1:pytorch官方教程与代码逐行详解

    官方教程网址:https://pytorch.org/tutorials/intermediate/seq2seq_translation_tutorial.html 代码所需数据源:https:// ...

  6. C#编码简单性之语义篇(如何编写简短的C#代码,随时更新)

    以前写C++的时候曾经在自己网站上发表过一个编码"简单性"之文章,现在编写C#了才发现自己无意之间就会写下一些浪费屏幕的代码. 下面是自己编码中偶然发现的一些案例,欢迎中等水平的编 ...

  7. java 重用性_提高Java代码重用性的三个方法

    三种修改现有代码提高其可重用性的方法,它们分别是:改写类的实例方法,把参数类型改成接口,选择最简单的参数接口类型. 措施一:改写类的实例方法 通过类继承实现代码重用不是精确的代码重用技术,因此它并不是 ...

  8. 用Groovy思考 第一章 用Groovy简化Java代码

    用Groovy思考  第一章 用Groovy简化Java代码 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs 1. Groovy的安装 目前Groovy的 ...

  9. ML之sklearn:sklearn的make_pipeline函数、RobustScaler函数、KFold函数、cross_val_score函数的代码解释、使用方法之详细攻略

    ML之sklearn:sklearn的make_pipeline函数.RobustScaler函数.KFold函数.cross_val_score函数的代码解释.使用方法之详细攻略 目录 sklear ...

  10. 对话框 未能返回新代码元素 可能 没有ncb_JDK1.8的新特性 | 技术

    黑马程序员 微信号:heiniu526 传智播客旗下互联网资讯,学习资源免费分享平台 JDK1.8目前在企业中已经广泛被应用,今天我们将学习以下方面的新特性: · Lambda表达式 · 函数式接口 ...

最新文章

  1. c++数据结构中 顺序队列的队首队尾_数据结构 3.3 顺序队
  2. java品酒会,我学 rxjava 2(3)- 热发射
  3. C语言:L1-034 点赞 (20分)(解题报告)
  4. arduino char*转string_Java 中 String 类的常用方法汇总
  5. 鸿蒙轻内核源码分析:异常钩子模块系统中断异常,如何转储异常信息
  6. python基于scipy拟合构建所需统计分析模型,可视化分析展示
  7. SpringMVC + security模块 框架整合详解
  8. 并发控制技术手段之时间戳(二)
  9. windows 2003 server安装iis6,附下载文件
  10. 力软快速开发平台源码7.0.6
  11. 主分区、扩展分区、逻辑分区和活动分区的区别与联系
  12. 【计算机网络】透明网桥:逆向学习算法逐步建立转发表(例题详细解析)
  13. TongWeb卡、TongWeb卡、TongWeb卡卡卡
  14. Eclips 快捷键设置
  15. 小米路由器LuCI Web服务
  16. 一篇文章读懂支付宝9.0改版背后的产品逻辑和战略布局
  17. 各行业的英语术语(绝对精华3)
  18. 一个专科生的程序员之路
  19. 流程控制之python
  20. Kylin(二)安装使用

热门文章

  1. [洛谷P4081][USACO17DEC]Standing Out from the Herd
  2. Windows autoKeras的下载与安装连接
  3. Dockerfile 中的 CMD 与 ENTRYPOINT
  4. clean-css 安装 使用
  5. HttpClient相关
  6. 分享一个强大的弹出框
  7. 中挪动正请求第三方支出牌照竖立支出公司
  8. 今天拿到一个TFS Workgroup Edition,想从B3R升级,结果开始了一天的艰难之路。。...
  9. java导出数据EXCEL的工具类(以spring-webmvc-4.0.4jar为基础)
  10. codeforce 604B More Cowbell