The code I’ve been looking at recently has quite some problems with managing various ids. The ids in the system are confusing on many levels, both syntactically and semantically.
- To begin with, there are a lot of them.
- They are represented using a mix of ints, longs and strings. Even the same id may be represented using different data types in different places.
- We’ve had bugs where an object with multiple ids has been put into a map using one of its ids as key and someone else tries to get it out using another id as key.
- Their names are sometimes confusingly similar.
- The same id may have multiple names, used intermixed.
Therefore, we’ve discussed various ways of getting a grip on the situation. One of the alternatives, which I think sounds rather good, is to use a separate class to represent each type of id.
For example, a
User class doesn’t have a
int userId field, but a
UserId userId field. How
UserId internally represents the id (perhaps as a long or string), is up to that class.
Some of the pros of this solution, from a Java perspective, are:
- When the id is used “out of context”, you don’t have to rely on variable naming to convey its meaning, you will get static type checking to help you.
- If you want to change the internal representation (int, long, etc), you only need to change a rather limited number of places instead of all over the system.
- You get an opportunity to create a suitable
hashCode(), and or
- You get a natural place for common convenience methods regarding the id, reducing the need for various “util classes” (which really are more procedural than object oriented).
The primary drawback that I can think of is that it generates a lot more small objects which may increase memory usage. But until it has been proven to be an actual problem in a specific case, I think that is a reasonable cost for the benefits above.