acm-header
登录

ACM通信

Kode恶性

一段不错的代码


好的代码标识

信贷:Flickr

回到顶部

在我的上一篇专栏文章(《系统不是产品》,8月通信)我提到我最近读了两段代码,它们实际上降低了,而不是升高了我的血压。正如所承诺的,本专栏将讨论第二段代码。

这是能让我真的就像一段代码,而不是那些明显的代码,比如得体的文档,适当的缩进,以及当函数或子系统被正确重用时合理的变量名称。在过去的一个月里,我一直在阅读由比萨大学的Luigi Rizzo编写的IPFW (IP防火墙)代码,它是FreeBSD中可用的防火墙之一。与任何防火墙一样,IPFW需要检查数据包,然后决定丢弃、修改或不改变数据包通过系统。在回顾了几个做类似工作的软件后,我不得不说IPFW在重用它周围的代码方面做得最好。这里有两个例子。

防火墙的部分工作是对数据包进行分类,然后决定如何处理它们。有几种方法可以做到这一点,但IPFW做的是相当优雅的。它重用了内核中另一个地方的一个经过尝试和测试的想法,BPF(伯克利包过滤器)。BPF使用一组opcodessort(类似于机器语言)对信息包进行分类,以决定信息包是否与用户指定的过滤器匹配。与手工编码规则相比,使用操作码和状态机进行分组分类可以使分组分类器的实现更加灵活紧凑。IPFW扩展了可用于对数据包进行分类的操作码集,但其思想是完全相同的,并且生成的代码易于阅读和理解,因此更容易维护,更不可能包含可能让恶意数据包通过的bug。在IPFW中执行任何和所有防火墙规则的整个状态机只有1200行C代码,包括注释。使用一组操作码来表示数据包处理规则的另一个优点是,整个C代码块(实际上是一个字节码解释器)可以被优化编译器生成的即时编译代码所替代。这将导致包处理速度的更大提高。

一种更直接的重用情况是IPFW如何直接重用内核的路由表代码来存储它自己的地址查找表。防火墙中的许多规则引用信息包的源地址或目的地址。虽然写你自己的例程来存储和检索网络地址是很有可能的,很多人都有,但没有必要重写这段代码,特别是当你的防火墙代码已经链接到一个程序,有这样的例程可用。内核中的基数代码可以管理任何类型的键/值查找,尽管它被优化为处理网络地址和相关掩码。IPFW表管理代码实际上只是对基数代码的一个简单包装,可以在附图中看到。

这段代码所做的全部工作就是接受IPFW能够理解的参数,例如规则链(ch)、地址表(资源描述)、地址(addr),并以基数代码(在第13行中调用)可用的方式将它们打包。该值在函数的最后一个参数中返回。表管理代码中的所有其他函数(在表中添加、删除和列出条目)看起来都非常相似。它们是基数代码的包装器。像IPFW那样将路由表代码作为一个库来处理,意味着编写不那么复杂和乏味的代码,并且只需要200行C代码(包括注释)就可以实现网络地址表。正是这种重用,而不是我经常遇到的那种折磨人的重用,让我赞扬了这段代码。

别担心,我相信下次我还会继续抱怨一些糟糕的代码,但我不得不说,在两个月内发现两个编写良好的代码片段是一个很好的惊喜。我认为这是某种记录。

KV

回到顶部

亲爱的KV

我当前项目中的一个人一直在抱怨我在代码中使用了“丰富多彩的隐喻”。虽然我理解我不应该检查这些东西到我们的源回购,但我不明白为什么当他在我的屏幕上看到它们时,他会抱怨。我通常使用这些词来调试消息,因为它们足够令人震惊,足以从我们的软件产生的其他日志消息中脱颖而出。我真的无法相信KV会反对程序员在日志信息中添加一点盐。

Kolorful小山

回到顶部

亲爱的Kolorful

鉴于我在本专栏中所写的一些内容,我可以理解为什么您会认为我可能是一个丰富多彩的隐喻的使用者。你是对的,我的同事可以告诉你,由于我在处理特别可怕的代码时偶尔会爆发,他们曾听到我说过一两个他们希望现在能忘记的事情。


当函数或子系统被正确地重用时,我就会真正成为一段代码。


不幸的是,至少对你来说,在这场争论中,我不得不站在你的同事一边。虽然我相信您已经忠实地标记了每个地方,但您的代码可能会用著名的注释“XXX Remove This!”发出一个丰富多彩的隐喻,但事实是,如果您做得足够多,总有一天,而且通常是在非常错误的一天,您将会忘记。你可能认为你不会,但不值得冒这样的风险。我经历过这样的麻烦,我很高兴,这一次,问题不是我的错。

十多年前,我为一家生产软件IDE(集成开发环境)和一些相关的低级软件的公司工作。在特定的平台上,IDE的限制之一是每个被IDE保存的项目都必须有一个适当的扩展名——在点之后的字母提供了刚刚保存的文件类型的线索。虽然程序员非常习惯于给他们的文件这样的描述性名称,如notes.txt、main.c和stdlib.h,但事实证明并不是每个人都熟悉这种命名标准,有些人甚至喜欢像Project1和Project2这样的名称,没有任何类型的标识扩展。

开发IDE的程序员决定,如果他的程序的用户拒绝向项目文件名添加扩展名,他就为他们添加一个。他选择了一个与duck押韵的四个字母的单词。我不确定他在发布时是否有意这样做,以指出那些拒绝使用文件扩展名的客户,或者这是否是他想在发布前更改的东西,但最终这并不重要。在我们发布IDE 1.0.1维护版本的几天内,发布了1.0.1b版本,只做了一个更改。我不记得b版本是否有说明说明发生了什么变化,但所有从事软件工作的工程师都知道真正的原因。

令人惊讶的是,这样做的程序员保住了他的工作。我怀疑这有两个原因,第一,他实际上是一个非常优秀的程序员,第二,他是公司中唯一一个愿意支持他所开发的平台上的IDE的人。

虽然这是一个非常极端的例子,说明色彩缤纷的比喻出了问题,虽然我知道有些程序员会在评论中留下非常强烈的语言,但我不得不说,我也不赞成这种做法。您的代码是您的遗产,虽然您的母亲可能永远不会看到它,但您仍然应该只检入不会让她感到震惊的代码,即使她选择阅读它。

KV

ACM队列的q戳相关文章
queue.acm.org

通过针眼来传递语言
罗伯托·伊鲁塞利姆西,路易斯·恩里克·德·菲盖雷多,瓦尔德马尔·塞莱斯
http://queue.acm.org/detail.cfm?id=1983083

语法海洛因
罗德尼•贝茨
http://queue.acm.org/detail.cfm?id=1071738

在生产环境中调试AJAX
埃里克·施洛克
http://queue.acm.org/detail.cfm?id=1515745

回到顶部

作者

乔治诉Neville-Neilkv@acm.org)是Neville-Neil咨询公司的所有者和ACM的成员队列编辑委员会。他从事网络和操作系统的代码编写工作,从中获得乐趣和利润,教授各种与编程相关的课程,并鼓励您发表与他有关的评论、妙语和代码片段通信列。

回到顶部

UT1表格一个好的代码的例子。

回到顶部


版权归作者所有。

数字图书馆是由计算机协会出版的。版权所有©2012 ACM股份有限公司


没有发现记录

登录为完全访问
»忘记密码? *创建ACM Web帐户
文章内容:
Baidu
map