3.7. Supporting Methods

Business rules can also be specified imperatively, using supporting methods. These methods are associated back to the class member (property, collection or action) using a simple prefix. For example, to imperatively disable the addItem() action for a Claim, we could use:

class Claim ... {

    void addItem(
            @Named("Days since")  int days,
            @Named("Amount")      double amount, 
            @Named("Description") String description) { 
       ...
    }
    String disableAddItem() {
        status == "Submitted" ? "Already submitted" : null
    }
    ...
}

Returning a non-null value means the action (or more generally class member) should be disabled; the string returned is the reason why the action cannot be invoked.

There are supporting methods for each of the three levels of business rules ("see it, use it, do it"), with the prefix being hideXxx(), disableXxx() and validateXxx(). The hideXxx() returns a boolean, the other two (as you've just seen) return a String. In the case of validateXxx(), the method takes arguments to allow validation to be performed, for example:

class Claim ... {

    ...
    String validateAddItem(int days, double amount, String description) {
        if (days <= 0) "Days must be positive value"
    }
    ...
}

There are a couple of other supporting methods that can be provided. The defaultXxx() prefix is used to provide a default either for a property of a newly instantiated object, or, more commonly, as the default for a parameter of an action. In the latter case the argument number is specified:

class Claim ... {

    ...
    int default0AddItem() { 1 }
    ...
}

In a similar vein, the choicesXxx() prefix provides a list of choices for a property or for an action parameter:

class Claim ... {

    ...
    List<String> choices2AddItem() { ["meal", "taxi", "plane", "train"] }
    ...
}

There's no requirement for choicesXxx() to tie in with validateXxx() or defaultXxx(), but they usually are consistent with each other.