何时使用常量作为参数而不是魔法值
我读过(并且普遍同意),为了提高代码的可读性,您应该使用常量而不是幻数作为方法参数。例如,使用 PHP:
// no constants ////////////////////
function updateRecord($id) {
if ($id == -1) {
// update all records
} else {
// update record with "id = $id"
}
}
updateRecord(-1); // future maintainer says: "wtf does -1 do?"
// and then has to jump to the function definition
// with constants: /////////////////
define('UPDATE_ALL', -1);
function updateRecord($id) {
if ($id == UPDATE_ALL) {
// update all records
} else {
// update record with "id = $id"
}
}
updateRecord(UPDATE_ALL); // future maintainer says: "woot"
是的,这不是一个很好的例子,我知道...
所以,我可以看到这是一个更好的事情,但它提出了一个问题您应该多久执行一次此操作?如果它适用于每个函数,那么您最终会得到大量的常量定义。
你会在哪里划清界限?始终坚持使用常量而不是幻数,还是根据相关函数的使用情况采取混合方法?
I have read (and generally agree) that to increase code legibility, you should use constants instead of magic numbers as method parameters. For example, using PHP:
// no constants ////////////////////
function updateRecord($id) {
if ($id == -1) {
// update all records
} else {
// update record with "id = $id"
}
}
updateRecord(-1); // future maintainer says: "wtf does -1 do?"
// and then has to jump to the function definition
// with constants: /////////////////
define('UPDATE_ALL', -1);
function updateRecord($id) {
if ($id == UPDATE_ALL) {
// update all records
} else {
// update record with "id = $id"
}
}
updateRecord(UPDATE_ALL); // future maintainer says: "woot"
Yeah, it's not a great example, I know...
So, I can see how this is a Better Thing, but it raises the question of how often you should do this? If it is for every function, you'd end up with a metric shirtload of constant definitions.
Where would you draw the line? Stick with constants over magic numbers all the way, or take a blended approach depending on the usage of the function in question?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果每个函数都采用“神奇参数”,那么你就已经做错了。
我总是使用常量。如果您认为这意味着您有太多常量,那么这只是反映了您设计中的其他缺陷。
If every function takes "magic parameters", then you're already doing it horribly wrong.
I would always use constants. If you think that means you have too many constants, then that's just reflecting other flaws in your design.
正如您已经指出的,未来的维护者将感谢您清晰的命名。这个维护者甚至可能是你,我一次又一次地惊讶于我忘记了我自己的代码,并且当我有一段时间没有处理它时再次理解它是多么困难。
只要范围大于单个简短方法,我肯定会一直使用常量。一旦开始传递这些值,恕我直言,它们必须被定义为常量。在方法内部,注释可能会起作用。然而,这并不能帮助任何看不到该注释的代码调用者。即使同一类中的另一个方法也应该被视为“API 客户端”,它不应该知道它在这方面调用的其他方法的实现细节。
使用支持“真实”枚举的语言(例如 Java 5 中引入的 Java
enum
关键字),您甚至可以获得类型安全性,并且不会面临基于整数的常量等可能出现的唯一性问题的风险。As you already pointed out, future maintainers will thank you for clear naming. This maintainer might even be you, I am amazed time and again about how much I forget about my own code and how hard it can be to understand it again when I haven't been working on it for a while.
I would definitely go with constants all the way, as soon as the scope is greater than maybe a single, short method. As soon as you start passing these values around, IMHO they must be defined as a constant. Inside a method a comment might do. This does not, however help any callers of your code that do not see that comment. Even another method in the same class should be considered an "API client" which should not know about the implementation details of other methods it calls in this regard.
With languages supporting "real" enumerations (like the Java
enum
keyword introduced in Java 5) you even gain type safety and do not risk uniqueness problems that for example integer based constants can have.我会在需要的地方使用它..
以 PHP 的 sort() 例如。这是有道理的:
但这会吗?
I would use it where it..
Take PHP's sort() for example. This makes sense:
But would this?
如果你将东西包装在类中并且使用类常量,那么这就不是什么问题了。除了事物路径之外,我很少使用全局常量。
Well its less of an issue if youre wrapping things in classes and you use class constants. I rarely use global constants except for things paths.
您应该尝试将代码中的文字保持在绝对最低限度:每个文字都是一个潜在的问题,因为您的环境可能会发生变化,并且其他开发人员可能不知道它的含义。
当我开始一个项目时,我总是专用一个仅用于命名常量的文件,通常包装在专用于此类的类中,并且我自由地使用它们,因为我的工作性质需要它。所有命名常量都驻留在该文件中,并由该文件进行控制,从而为您提供对命名常量的出色组织和控制。您还可以使用注释或代码区域将它们组织成组,并根据语言进行嵌套和构建。
这种做法多年来对我帮助不已。
You should try to keep literals in your code to an absolute minimum: Every literal is a potential problem, because your environment can change, and because other developers may not know what it means.
When I start a project, I always dedicate a file to be used only for named constants, often wrapped in a class dedicated to such, and I make liberal use of them, since the nature of my work requires it. All named constants reside in that file, and are controlled from that file, giving you excellent organization and control over your named constants. You can also organize them into groups with comments or code regions, and depending on the language, nest and build one upon the other.
This practice has help me endless times over the years.