什么是幻数,为什么它不好?

什么是幻数?

为什么要避免它?

有没有适合的情况?


幻数是代码中数字的直接用法。

例如,如果您有(使用Java):

public class Foo {
    public void setPassword(String password) {
         // don't do this
         if (password.length() > 7) {
              throw new InvalidArgumentException("password");
         }
    }
}

这应该重构为:

public class Foo {
    public static final int MAX_PASSWORD_SIZE = 7;

    public void setPassword(String password) {
         if (password.length() > MAX_PASSWORD_SIZE) {
              throw new InvalidArgumentException("password");
         }
    }
}

它提高了代码的可读性,并且更易于维护。 想象一下我在GUI中设置密码字段的大小的情况。 如果我使用魔术数字,每当最大尺寸发生变化时,我必须在两个代码位置进行更改。 如果我忘记了一个,这会导致不一致。

JDK充满了IntegerCharacterMath类中的例子。

PS:FindBugs和PMD等静态分析工具会检测代码中使用的幻数,并提出重构建议。


幻数是一个硬编码值,可能在稍后阶段发生变化,但难以更新。

例如,假设您有一个页面显示“您的订单”概览页面中的最后50个订单。 50是这里的魔术数字,因为它不是通过标准或惯例设置的,它是一个由规格中概述的原因弥补的数字。

现在,你所做的是你在不同的地方有50个 - 你的SQL脚本( SELECT TOP 50 * FROM orders ),你的网站(你的最后50个订单),你的订单登录( for (i = 0; i < 50; i++) )和其他许多地方。

现在,当有人决定改变50到25时会发生什么? 或75? 或153? 你现在必须在所有地方替换50个,你很可能会错过它。 查找/替换可能不起作用,因为50可能用于其他事情,并且盲目地用50替换50可能具有一些其他不良副作用(即,您的Session.Timeout = 50调用,也被设置为25并且用户也开始报告频繁超时)。

而且,代码可能很难理解,即“ if a < 50 then bla ” - 如果在复杂函数中遇到这种情况,其他不熟悉代码的开发人员可能会问自己“WTF是50? ?”

这就是为什么最好在1个地方有这样的模糊和任意数字 - “ const int NumOrdersToDisplay = 50 ”,因为这样可以使代码更具可读性(“ if a < NumOrdersToDisplay ”,它也意味着您只需要将其更改为1明确的地方。

Magic Numbers适用的地方是通过标准定义的所有内容,即SmtpClient.DefaultPort = 25TCPPacketSize = whatever (不确定是否标准化)。 而且,只有在1个函数中定义的所有东西都可以接受,但这取决于上下文。


你有没有看过维基百科条目的幻数?

它详细介绍了魔术数字参考的所有方法。 这里有一个关于幻数的引用是一个不好的编程习惯

术语幻数也指在源代码中直接使用数字而不解释的糟糕编程习惯。 在大多数情况下,这会使程序难以阅读,理解和维护。 尽管大多数指南对数字0和1都有例外,但将代码中的所有其他数字定义为命名常量是一个好主意。

链接地址: http://www.djcxy.com/p/64417.html

上一篇: What is a magic number, and why is it bad?

下一篇: Gxt combo box selection arrow is not properly aligned in GXT4.0