I think that some of my college classes took points off your grade for using literal strings instead of #define. Likewise, linters and coding standards typically want to prevent programmers from using literals.
Many indoctrinated programmers, therefore, insist that the correct way of writing a select statement is something like this:
"select " + COLUMN_NAME + ", " + COLUMN_EMAIL + " from " + TABLE_PEOPLE + " where " + COLUMN_ID + " = ? "
This jihad gains its supposed righteousness from the idea that literals make your code less maintainable. But, aside from thorough tests, what does make code maintainable? In order of importance:
- Fewer dependencies
- All else equal, shorter is better
So, assume for a moment that the most maintainable code is the most readable code, and compare:
"select name, email from people where id = ?"
I suggest that the second statement is far more readable, and therefore more maintainable. It is also shorter, even without including the constant declarations, and it removes a dependency on constants defined somewhere else.
Ha! You’re ignoring the dependency on the database structure. If I want to change a column or table name, the first code is dryer.
Perhaps, but structural database changes are complex and should not be undertaken with the flippant attitude that you can do them simply by changing the value of a constant somewhere. Consider, just for starters, that if you change column name “email” to, say, “primary_email”, you will probably want to change the name of the constant to match and you will still have to search for any places the string literal might have been used, just in case.
Ok, but at least I will spend less time tracking down bugs related to spelling errors.
Sure, but seriously, how much time do you spend on spelling errors? They are typically among the easiest bugs to fix. The cumulative effort of fixing typos is less than the effort involved in managing your constants.
Life without literals is burdensome. Where should the constant declaration go? Does a definition for the same value already exist in scope? If it does, and has the same name as what you want to use, does it refer to the same thing? You add a “department” table that also has a “name” column; should you (a) use the existing constant, (b) make a new constant with a non-conflicting name, (c) rename the existing constant or, (d) both b and c?
But we have a coding standard that says what to do, so I can just follow that.
That’s just one more thing you need to remember. Do you remember precisely what your coding standard says to do? Does it even cover every case?
Does your coding standard say that uppercase identifiers must never be built from external data? Even if it does, unless you can see the constant definition in the same screenful of text as where it’s used, your code is not obviously safe from injection.
Instead of taking on this travail, just funnel your energy into picking good names for your tables, urls, or whatever in the first place. You’ll need fewer structural changes later.
Good points, but constants can add meaning, instead of being “magic numbers” sprinkled about.
True, adding meaning (see “readability”) is the one good reason for a constant instead of a literal, but usually this applies only to numbers, not strings.
What about localization?
Well… there are some good arguments for externalizing strings that appear to users, but that’s another article.