There are several basic rules for designing a domain object. These rules keep safety and correctness in mind:
- Always implement
- I have seen many memory leaks from inadvertent caches of domain objects which used object identity. When implementing
hashCode, only compare primary keys since that is the sense of equality the persistence layer uses.
- Mark immutable fields
finaland provide no setters for them
- Always mark primary keys
finaland only set them in a constructor. This means there is no default constructor.
- Include all required fields in constructors
- Never leave domain objects in an inconsistent state. The constructors should reflect this fact. Again that means no default constuctor.
- Test the inputs of non-
- Simply provide
if (null == someField) throw new NullPointerException();in the constructor or setter which takes someField. If the field is not required, make the same check in the getter as it may have not been initialized yet.
Comparableif there is a default sort order
- Whenever domain objects have any kind of natural sort order, always implmement
Comparable. Do not force other code to do the work on behalf of the domain object. And remember to compare as many fields as needed by the sort order. For example, a
CustomerNamecomparator needs to sort on lastName, firstName, middleName and nameSuffix.
- Do not use
toStringfor business code or display. For those, use business-specific methods such as
displayAs. Commons-lang provides an excellent
Unfortunately, not all of them can be used with every project. For example, if you persist domain objects directly rather than using an intermediate persistence layer to represent database tables (e.g., Hibernate or iBatis), the framework requries that every instance field have a bean-like getter/setter. (Actually, recent Hibernate supports direct field access, but this is still uncommon with many projects.)