Wrap IDs in objects
In Java, I like to wrap ID values in objects, rather than just passing them around the code as their native "int" or "long" or "String" values.
The reasons are twofold why using an object is better:
- Code becomes more readable, for example
foo(LoginId x)is more readable than
foo(long x). (Although perhaps neither foo nor x are good names, so perhaps the example over-exaggerates this improvement.)
- The compiler can do more checking. If you pass the ID of one type of object (as a long) to a function expecting the ID of a different type of object (as a long), the compiler cannot warn you of your mistake. This becomes particularly relevant if you have a function taking two IDs and you pass them the wrong way around.
Things to consider when writing such an "ID object"
- Do not allow the ID contained within the object to be null. Having "LoginId x" where x is not null, but the value contained within x is null, makes no sense. (For example, use primitive types if dealing with numerical IDs, as they cannot be null.)
- If the ID is a string, don’t allow this string to be empty; same as above.
- Implement equals and hashCode methods so that these IDs can be used within Sets, or as keys within Maps, or as keys in Wicket drop-downs, or wherever.
- Make them serializable.
- Make the ID attribute a "public final" attribute. That means useless getter methods can be avoided, from the object itself and from client code.
- The object should have a single constructor which takes the value and sets it in the attribute.
- Implement toString so that the debugger can display the object usefully.