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.