Tuesday, September 07, 2004

Advice to persistence frameworks

In my previous post I described how to make good domain objects in Java. However, much of the advice is circumscribed by limitations in popular persistence layers below the domain objects. Therefore, I have some advice to persistence layer authors.

Support non-default constructors. Admittedly, this takes some cleverness. Say you have a class like this:

public class Foo {
    private final int count;
    private final int total;
    private int numberOfMonkeysInABarrel;

    public Foo(final int count, final int total) {
        this.count = count;
        this.total = total;
    }

    public int getPercentage() {
        return Math.round((float) (count * 100) / total);
    }

    public void setNumberOfMonkeysInABarrel(final int n) {
        numberOfMonkeysInABarrel = n;
    }

    public int getNumberOfMonkeysInABarrel() {
        return numberOfMonkeysInABarrel;
    }
}

A really clever persistence layer can work out what the inputs are for the constructor by noting the following:

  1. The Sun VM returns reflected fields in order of declaration. The documentation does not specify an order, however, so even though this is emprically true in JDK 1.4 and 5.0 VMs, this is a logically weak link.
  2. For given fields, filtering is easy to find just private final fields.
  3. By requiring than the order of inputs for a constructor match the ordering of fields (very common by convention), it is mechanical to match up constructor inputs to required fields, assuming required fields are declared private final.

And there you go: a persistence layer can create domain-safe instances without requiring an otherwise useless default constructor or getters and setters.

No comments: