Articles in Variable Names
They add little to no value in most cases, but make the code longer to read.
Usually, I'd rarely have a the need for the distinction between a "a" or "the" in the flow of a function, so it doesn't make sense to use articles.
It's a formal programming language and I am fine with it not reading exactly like a natural language. In fact, it's probably better this way, not everything's necessarily so great about natural languages.
There are a few cases where readability can benefit from using articles though, for instance if you want to implement a checker for a "is a" relationship with a method signature like boolean isA(Object o, Class<?> cl)
(I'm not advocating this to be a good idea).
Hard-Coded Strings
It depends on whether you plan to reuse them or not, and whether that reuse is driven by semantics (and not just the fact that the String has the same content in different places) and spread across multiples classes or sub-systems.
To that extent, I usually use these rules:
If you have the same string multiple times and it has the same meaning acros multiple classes, then extract to constants in an interface.
If you have the same string multiple times within a single class and it has the same meaning within that class, then extract to constants within the class.
If you have only a few number of repetitions of as tring, or they just happen to be identical but aren't guaranteed to always be in the future, then I'd leave them inlined.
If any of the above would render maintenance difficult, screw rules 1 to 3 and do whatever works best for you.
Of course, make sure that the constant's name makes the code as semantically valid as the string it holds. That also applies for other things that aren't strings (like Predicates, for instance).
I would approach this problem as I would approach any localization issue: ResourceBundle. I use a class called I18n
that has a static method called getMessage
that takes a key and optionally a list of arguments. The key gets looked up in a ResourceBundle
configured to use the default Locale
or whatever you prefer (specifics here aren't important, so long as the caller to I18n
doesn't have to know about what the Locale
is).
The I18n
class is as follows:
public final class I18n {
private I18n() {
}
private static ResourceBundle bundle;
public static String getMessage(String key) {
if(bundle == null) {
bundle = ResourceBundle.getBundle("path.to.i18n.messages");
}
return bundle.getString(key);
}
public static String getMessage(String key, Object ... arguments) {
return MessageFormat.format(getMessage(key), arguments);
}
}
In your project, you would have in package path.to.i18n, files containing messages.properties (default), messages_en.properties (Locale en), messages_it.properties (Locale it), etc.
When you need to translate an enum value, you shouldn't have to treat it any differently than any other key, except the key is the enum term.
In other words, you have:
public enum AccountStatusEnum {
Active,
Inactive,
Pending
}
When you call I18n.getMessage
, you pass with AccountStatusEnum.Active.toString()
and the translation will be found in a property file with key "Active". If you're like me, and you prefer to use lower-case keys, then you should perform toLowerCase()
on the string. Better still, you create a new I18n.getMessage
that takes an Enum rather than a key, and that method calls the String version of I18n.getMessage
with the enum value converted to string and in lowercase.
So you'd then add this to the I18n
class:
public static String getMessage(Enum<?> enumVal) {
return getMessage(enumVal.toString().toLowerCase());
}
I prefer to use this method because it incorporates the same translation logic in the same part of the program without impacting your design. You may even want to differentiate enum keys from your other keys, in which case you can begin each enum key with "enum.", so you would prepend "enum." when calling getMessage
. Just remember to name your keys in your properties files accordingly.
I hope that helps!
Best Answer
Yes, it absolutely is. Its the same as with usual classes and polymorphism:
versus
In this particular case it seems as if
flower.ordinal()
would work just as well.