Table of Contents
Abstract
Naked Objects uses convention over configuration and annotations to build the metamodel of the domain objects. This chapter explains what those conventions look like, and where annotations should be applied, when developing domain objects in Groovy.
Naked Objects allows validation and other business constraints to expressed either declaratively (using annotations) and/or imperatively (using supporting methods). For a given class member (property, collection or action) we can specify whether the member:
is visible, and if so, is it
is usable, and if modified, whether the proposed change
is valid
Or, slightly more pithily, can you see it, can you use it, can you do it.
Any public methods that don't represent properties or collections are interpreted as being actions. These are surfaced in the UI (as menu items or buttons) to provide arbitrary business behaviour (this is what makes Naked Objects applications more than a simple CRUD framework).
There are also a number of reserved method names that are used either as rendering hints or to define lifecycle callbacks.
Collectively these conventions and annotations define the Naked Objects Programming Model. This chapter should give you a good flavour of what it's like to writing applications for this programming model; but refer to the Naked Objects documentation for the complete reference.
The code fragments that follow are taken from the Groovy Objects' own test application (see the Groovy Objects subversion repository).
Typically domain objects subclass from
AbstractDomainObject
(in the Naked
Objects applib, transitively referenced from Groovy
Objects' own applib); for example:
class Claim extends AbstractDomainObject { ... }
It isn't mandatory to subclass from
AbstractDomainObject
. All that Naked
Objects requires is that it can inject its
DomainObjectContainer
into the domain object to
support lazy loading and dirty tracking (the
resolve()
and
objectChanged()
methods, normally called by
CgLib proxies). The DomainObjectContainer
also
allows your domain object to be able to instantiate and persist new
instances (using the newTransientInstance()
and
persist()
methods).
In practical terms, then, if you aren't able or don't want to
subclass from AbstractDomainObject
, just make
sure you push down the above methods into your own objects (probably by
way of a project-specific superclass).