以前被称为每日WTF的网站有一篇题为“软编码”的文章,其中包含以下摘录:
大多数程序员认为“硬编码”是一件坏事:它是一种类似黑客的、不优雅的、全面的惰性代码。因此,许多程序员尽其所能来避免它。不幸的是,这种回避的追求往往会导致一条更糟糕的道路:复杂、卷积和全面不可维护的代码。我喜欢把这称为软编码。 在讨论软编码的细节之前,我想简要地定义一下硬编码。它是一种将“不应该出现在源代码中的东西”直接嵌入到源代码中的实践。定义故意含糊不清:虽然大多数人都同意数据库连接字符串和日志文件目录不属于源代码,但存在许多灰色区域。以下面的代码为例:
private void attachSupplementalDocuments()
{
if (stateCode == "AZ" || stateCode == "TX") {
//SR008-04X/I are always required in these states
attachDocument("SR008-04X");
attachDocument("SR008-04XI");
}
if (ledgerAmnt >= 500000) {
//Ledger of 500K or more requires AUTHLDG-1A
attachDocument("AUTHLDG-1A");
}
if (coInsuredCount >= 5 && orgStatusCode != "CORP") {
//Non-CORP orgs with 5 or more co-ins require AUTHCNS-1A
attachDocument("AUTHCNS-1A");
}
}
我已经能感觉到你们中的一些人在畏缩:神奇的数字;字符串文字;哇,这可是一大堆硬编码啊!然而,在这个例子中没有一个字符是硬编码的:在上面的代码中没有“不应该在源代码中”的东西。该功能只是用非常清晰和特定的代码实现了非常清晰和特定的业务需求。少一点就会被软编码。
我认为,每日WTF扩展到描述最佳实践,而不是简单地对糟糕的代码幸灾乐祸,这是一个值得称赞的目标。我猜这是Jeff Atwood在他的《What’s Wrong With the Daily WTF》中发表的一些评论引起的。然而,我在本文中遇到的问题是,它将硬编码和使用魔法数字(或魔法字符串)之间的区别混为一谈了。
维基百科对硬编码的定义如下:
硬编码是指将输出或配置数据直接嵌入程序或其他可执行对象的源代码或数据的固定格式的软件开发实践,而不是从外部来源获取数据,或者用给定的输入在程序本身中生成数据或格式化。
例如:固定安装路径 如果一个Windows程序被编程为始终安装到C:\Program Files\Appname,而有人出于空间或组织的原因试图将它安装到不同的驱动器,它可能无法安装或在安装后运行。
例如:启动盘 一些“复制保护”程序在启动时查找软盘上的特定文件,以验证它们不是盗版。如果这台电脑被更新到一台没有软盘驱动器的新电脑上,程序就无法运行,因为软盘无法插入。
维基百科对魔法值的定义如下:
“神奇数字”这个术语也指在源代码中直接使用数字而不作解释的糟糕编程实践。在大多数情况下,这使得程序更难阅读、理解和维护。尽管大多数指南都对数字0和1做了例外,但将代码中的所有其他数字定义为命名常量是一个好主意。
这是可取的,有以下几个原因:
硬编码是不好的,因为它假定应该灵活的信息实际上是固定不变的。另一方面,使用神奇数字是一个代码维护问题,这并不一定意味着程序是不灵活的。