什么是幻数,为什么它不好?
什么是幻数?
为什么要避免它?
有没有适合的情况?
幻数是代码中数字的直接用法。
例如,如果您有(使用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充满了Integer
, Character
和Math
类中的例子。
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 = 25
或TCPPacketSize = 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