When to use constants as parameters instead of magic values
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 fun开发者_如何学Cction in question?
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.
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.
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.
I would use it where it..
- improves readability
- helps you remember
- let's you see at a glance what you are passing as an argument
Take PHP's sort() for example. This makes sense:
sort($array, SORT_NUMERIC);
But would this?
sort($array, 2); // Haven't actually dug in to see what it matches, but you get the point
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.
精彩评论