什么是神奇数字?

为什么要避免呢?

有没有合适的情况?


当前回答

那么返回变量呢?

我发现在实现存储过程时尤其具有挑战性。

想象下一个存储过程(我知道语法错误,只是举个例子):

int procGetIdCompanyByName(string companyName);

如果该公司存在于特定的表中,则返回该公司的Id。否则,返回-1。 不知何故,这是一个神奇的数字。到目前为止,我读到的一些建议说,我真的必须设计这样的东西:

int procGetIdCompanyByName(string companyName, bool existsCompany);

顺便问一下,如果公司不存在,它应该返回什么?它会将existesCompany设为false,但也会返回-1。

Antoher的选择是做两个独立的功能

bool procCompanyExists(string companyName);
int procGetIdCompanyByName(string companyName);

因此第二个存储过程的先决条件是公司存在。

但是我害怕并发,因为在这个系统中,一个公司可以由另一个用户创建。

顺便说一句,最重要的是:你对使用这种相对已知和安全的“神奇数字”来判断某事不成功或某事不存在有什么看法?

其他回答

我想这是在回答你之前的问题。在编程中,魔数是一个没有解释就出现的嵌入数字常数。如果它出现在两个不同的位置,则可能导致一个实例被更改而另一个实例未更改的情况。出于这两个原因,在使用数值常数的地方之外隔离和定义数值常数是很重要的。

在编程中,“神奇的数字”是一个值,它应该被赋予一个符号名称,但却被作为文字插入到代码中,通常在多个地方。

它不好的原因与SPOT (Single Point of Truth)好的原因是一样的:如果以后想更改这个常量,就必须遍历代码以找到每个实例。这也很糟糕,因为其他程序员可能不清楚这个数字代表什么,因此出现了“魔术”。

人们有时会进一步使用神奇数字消除,将这些常量移到单独的文件中作为配置。这有时是有帮助的,但也会带来更多的复杂性。

在类的顶部用默认值初始化一个变量怎么样?例如:

public class SomeClass {
    private int maxRows = 15000;
    ...
    // Inside another method
    for (int i = 0; i < maxRows; i++) {
        // Do something
    }

    public void setMaxRows(int maxRows) {
        this.maxRows = maxRows;
    }

    public int getMaxRows() {
        return this.maxRows;
    }

在这种情况下,15000是一个神奇的数字(根据CheckStyles)。对我来说,设置一个默认值是可以的。我不想做的事情是:

private static final int DEFAULT_MAX_ROWS = 15000;
private int maxRows = DEFAULT_MAX_ROWS;

这会让它更难读吗?在安装CheckStyles之前,我从未考虑过这一点。

关于使用神奇数字,还有一个问题没有被提及……

如果你有很多这样的数字,很有可能你有两个不同的目的,你使用魔法数字,其中的值碰巧是相同的。

然后,果然,你需要改变值…只有一个目的。

魔术数字也可以是具有特殊的硬编码语义的数字。例如,我曾经看到一个系统,其中记录id > 0被正常对待,0本身是“新记录”,-1是“这是根”,-99是“这是在根中创建的”。0和-99将导致WebService提供一个新的ID。

这样做的不好之处在于,您重用了用于特殊功能的空间(记录id的有符号整数的空间)。也许您永远不希望创建ID为0或ID为负的记录,但即使不是这样,每个查看代码或数据库的人都可能在一开始无意中发现这一点并感到困惑。不用说,这些特殊的值并没有得到很好的记录。

可以说,22、7、-12和620也可以算作神奇数字。: -)