编写糟糕的代码

正如每个开发者所知,编写糟糕的代码似乎比编写优质的代码容易得多。我们可以 将优质代码定义为易于理解且安全更改的代码。因此,糟糕的代码则相反,它非常难以阅读和理解其试图解决的问题。我们害怕更改糟糕的代码——因为我们知道很可能会破坏某些功能。

我自己与糟糕代码的纠葛可以追溯到我的第一个值得注意的程序。这是一个为学校比赛编写的程序,旨在帮助房地产经纪人协助客户找到理想的房子。这个程序是在学校的 8 位 Research Machines 380Z 计算机上用 Microsoft Disk BASIC 9 编写的,这是 1981 年对 Rightmove 的回应。

在那个互联网尚未普及的时代,它作为一个简单的桌面应用程序存在,带有基于文本的绿色屏幕用户界面。它不需要处理数百万,更不用说数十亿的用户。它也不需要处理数百万套房屋。它甚至没有一个漂亮的用户界面。

作为一段代码,它是几千行 Microsoft Disk BASIC 9 代码。没有代码结构可言,只有数千行代码,充斥着不均匀的行号和全局变量。为了增加挑战性,BASIC 限制每个变量名只能有两个字母。这使得代码中的每个名称都完全难以理解。源代码故意写得尽可能少用空格,以节省内存。当你只有 32KB 的内存来容纳所有程序代码、数据和操作系统时,每一个字节都很重要。

这个程序只提供了基本功能。用户界面是当时的风格,仅使用基于文本的表单。它比图形操作系统早了十年。该程序还必须实现自己的数据存储系统,使用 5.25 英寸软盘上的文件。同样,经济实惠的数据库组件是未来的事情。该程序的主要功能是用户可以搜索特定价格范围和功能集的房屋。他们可以根据卧室数量或价格范围等条件进行过滤。

然而,代码本身确实是一团糟。你自己看看——这是原始代码清单的照片:

image 2025 01 10 19 24 31 340
Figure 1. Figure 1.1 – The estate agent code listing

这种恐怖是其中一个开发版本的原始纸质清单。正如你所见,它完全不可读。不只是你。没有人能轻松阅读它。我也不能,尽管是我写的。我甚至可以说这是一团糟,是我亲手一个按键一个按键打出来的。

这种代码是噩梦般的存在。它不符合我们对优质代码的定义。阅读这段代码并理解它应该做什么并不容易。更改这段代码也不安全。如果我们尝试更改,我们会发现我们永远无法确定是否破坏了某些功能。我们还必须手动重新测试整个应用程序。这将非常耗时。 说到测试,我从未彻底测试过这段代码。它都是手动测试的,甚至没有遵循正式的测试计划。最多,我可能运行了一些简单的 “快乐路径” 手动测试。这些测试只是确认你可以添加或删除房屋,并且一些代表性的搜索功能有效,但仅此而已。我从未测试过代码的每一条路径。我只是猜测它会工作。

如果数据处理失败了,我也不会知道发生了什么。我从未尝试过。所有可能的搜索组合都有效吗?谁知道呢?我当然不知道。我甚至没有耐心去完成所有那些繁琐的手动测试。它确实工作了,足以赢得某种奖项,但它仍然是糟糕的代码。

理解为什么糟糕的代码会被编写

在我的案例中,这仅仅是因为知识的缺乏。我不知道如何编写优质的代码。但也有一些与技能无关的原因。没有人会故意编写糟糕的代码。开发者会尽他们所能,利用可用的工具和当时的能力做到最好。

即使具备正确的技能,以下几个常见问题也可能导致糟糕的代码:

  • 由于项目截止日期,缺乏时间优化代码

  • 处理遗留代码,其结构阻碍了新代码的干净添加

  • 为紧急的生产故障添加短期修复,但从未重新改进它

  • 对代码的主题领域不熟悉

  • 对本地习惯用法和开发风格不熟悉

  • 不适当地使用来自不同编程语言的习惯用法

既然我们已经看到了一个难以处理的代码示例,并了解了它是如何产生的,接下来让我们转向一个显而易见的问题:我们如何识别糟糕的代码?