Is it ever a good idea to hardcode values into our applications? Or is it always the right thing to call these types of values dynamically in case they need to change?
|
Yes, but do make it obvious. Do:
Don't:
|
|||||||||||||||||||||
|
|
As an addition to other answers. Use constants for strings when possible. Of course, you don't want to have
but you should have
(assuming you actually have a query where you want to get all the results from a specific table, always) Other than that, use constants for any number other than 0 (usually). If you need a permission bitmask of 255, don't use
instead use
Of course, along with constants, know when to use enumerators. The above case would probably fit well in one. |
|||||||||||||||
|
|
There are various reasons for assigning an identifier to a number. If the number might change, it should have an identifier. It's much easier to find NUMBER_OF_PLANETS than to search for every instance of 9 and consider whether it should be changed to 8. (Note that user-visible strings might have to change if the software ever has to be used in a different language, and that's a hard thing to predict in advance.) If the number is hard to type in any way. For constants like pi, it's better to give one maximum-precision definition than to retype it in several places, possibly inaccurately. If the number occurs in different places. You shouldn't have to look at two uses of 45 in adjoining functions and wonder if they mean the same thing. If the meaning isn't instantly recognizable. It's safe to assume that everybody knows what 3.14159265... is. It isn't safe to assume that everybody will recognize the gravitational constant, or even pi/2. ("Everybody" here does depend on the nature of the software. Systems programmers can be expected to know the octal representation of Unix permission bits or the like. In naval/marine architecture software, checking the Froude number of a proposed hull and speed to see if it's 1.1 or greater might be perfectly self-explanatory to anybody who should be working on it.) If the context isn't recognizable. Everybody knows there are 60 minutes in an hour, but multiplying or dividing by 60 may be unclear if there's no immediate indications that the quantity is a time value or a rate value. This gives us criteria for hard-coding literals. They should be immutable, not hard to type, occurring in one place or context only, and with recognizable meaning. There's no point in defining 0 as ARRAY_BEGINNING, for example, or 1 as ARRAY_INCREMENT. |
|||
|
|
I hardcode values only if the values are specified in the Specification (on a final release of the specification), e.g. The HTTP OK response will always be
Otherwise, I store constants in the properties file. The reason why I specified specifications, is that changing constants in specifications requires change management, in which, the stakeholders will review the change and approve/disapprove. It never happens overnight and takes months/years for an approval. Don't forget that many developers uses specifications (e.g. HTTP) so changing it means breaking millions of systems. |
||||
|
|
|
|||
|
|
|
What I find odd about this Q&A so far is that nobody has actually attempted to clearly define "hard-code" or, more importantly, the alternatives. tl;dr: Yes, it is sometimes a good idea to hard-code values, but there's no simple rule as to when; it depends completely on context. The question does narrow it down to values, which I take to mean magic numbers, but the answer to whether or not they're a good idea is relative to what they're actually used for! Several examples of "hard-coded" values are:
I probably left out several scenarios but I think that covers most of them. So, yeah, it's sometimes acceptable practice to hard code stuff. Just don't be lazy about it; it should be a conscious decision rather than plain old sloppy code. |
|||
|
|
|
It depends what you consider hardcoding. If you try to avoid any and all hardcoded things, you end up in softcoding territory, and make a system that only the creator can manage (and that's the ultimate hardcode) Plenty of things are hardcoded in any reasonable framework and they work. i.e. there's no technical reason why I shouldn't be able to change the entry point of a C# application (static void Main), but hardcoding that does not create any problems for any user (except the occasional SO question) The rule of thumb I use is that anything that can and will change, without affecting the state of the whole system, should be confugurable. So, IMHO, it's silly not to hardcode things that are never changing (pi, gravitational constant, a constant in a mathematical formula - think volume of a sphere). Also it's silly not to hardcode things or processes that will have an impact on your system that will require programming in any instance, i.e. it's wastefull to allow the user to add dynamic fields to a form, if any added field would require the maintenance developer to go in and write some script that will make that thing to work. Also it's stupid (and I've seen it a few times in enterprise environments) to create some configuration tool, so nothing is hardcoded, yet, only the developers in the IT department can use it, and it's only slighty easier to use it than to do it in Visual Studio. So, bottom line, whether a thing should be hardcoded is a function of two variables:
|
|||
|
|
|
I recently coded a MySQL function to properly calculate the distance between two lat/long pairs. You can't just do pythagorus; longitude lines get closer together as latitude increases toward the poles, so there's some kinda hairy trig involved. Point is, I was pretty torn about whether to hard-code the value representing the earth's radius in miles. I ended up doing it, even though the fact is, lat/lng lines are much closer together on, say, the moon. And my function would drastically underreport distances between points on Jupiter. I figured the odds of the website I'm building having an extraterrestrial location get entered is pretty slim. |
|||
|
|
|
I've noticed that any time you can extract data from your code, it improves what's left. You start noticing new refactorings and improving whole sections of your code. It's just a good idea to work towards extracting constants, don't consider it some stupid rule, think about it as an opportunity to code better. The biggest advantage would be the way you might find similar constants being the only difference in groups of code--abstracting them into arrays has helped me reduce some files by 90% of their size and fix quite a few copy & paste bugs in the meantime. I've yet to see a single advantage to not extracting data. |
|||
|
|
|
Well it depends if your language is compiled. If it's not compiled, it's not a big deal, you just edit the source code, even if it will be slightly delicate for a non programmer. If you are programming with a compiled language, this is clearly not a good idea, because if the variables change, you have to recompile, which is a big waste of time if you want to adjust this variable. You don't need to make some slider or interface to dynamically change his variable, but the least you could do is a text file. For example with my ogre project, I'm always using the ConfigFile class to load a variable I have written to a config file. |
|||
|
|
|
Two occasions where constants are (in my opinion at least) OK:
|
|||
|
|
|
I do agree completely with Jonathan but as all rules there are exceptions... "Magic number in the spec: Magic number in the code" Basically states that any magic numbers that remains in the spec after reasonable attempts to get descriptive context for them should be reflected as such in the code. If magic numbers remain in the code every efforts should be made to isolate them and make them clearly linked to their point of origin. I have performed a few interfacing contracts where it is necessary to populate messages with values mapped from the database. In most cases the mapping is fairly straight forward and would fit in Jonathan's general guide lines but I have encountered cases where the target message structure was just plain awful. More than 80% of the values that had to be passed down in the structure were constants enforced by the specification of the distant system. this coupled with the fact that the message structure was gargantuan made that a LOT of such constants had to be populated. In most cases they did not provide a meaning or reason, just said "put M here" or "put 4.10.53.10100.889450.4452 here". I did not attempt either to put a comment next to all of them it would have rendered the resulting code unreadable. I did however make sure the code sections where these magic values appear are properly isolated and that their containers (classes, packages) named appropriately to point directly to the specification enforcing them. That said, when you think about it... it's pretty much all about making it obvious... |
|||
|
|
|
If you're hardcoding the value of the earth's gravitational constant, noone's going to care. If you hardcode the IP address of your proxy server, you're in for trouble. |
|||||||||||
|
|
Mostly no, but I think that is worth noting that you will have the most problems when you start duplicating the hard-coded value. If you don't duplicate it (ex. use it just once in the implementation of a class) then not using a constant might be alright. |
|||
|
|
Alice: Oh, no, no. I was just wondering if you could help me find my way. Say, just what kind of applications are you writing anyway? |
|||||||||||||||||
|
pimight change... – Gabe Apr 14 '11 at 4:46