Creating the Object Model
With the web framework running and with some familiarity, you should be ready to get into developing. Instead of
building from the web inward, we'll build out to the web. In this way, the solution should be more appropriate for
the situation, and less constrained by technicalities. A better outcome will result from initially focusing on a solid object model.
We'll be using the repository for object persistence and will use some of the repository concepts within these classes.
Consult the repository tutorial for more indepth information about designing objects for, storing and
retrieving objects.
The goal of the the music library project is to manage albums and artists. We'll start with the classes: Album, Artist, Group and
Track. The object model is a bit big to describe in full details, so I'll leave it up to you
browse the source in src/java/doc/walkthru and javadoc.
Only the details for specific points of interest are described here.
Interfaces
I like to make interfaces for the model objects, as it allows for addressing the definition (interface) without having to worry about
the details of the implemention (class). Album, Artist, Group and Track are all interfaces which describe
the general use of an object, but not how the processing itself is done. We'll start with
the obvious:
An album is a named, arranged collection of tracks performed by an artist or artists, in the case of a
compilation. An album is released in some sort of format.
A track is contained on an album and performed by a performer, be it a group
or an artist.
A track is performed by a performer, and may be an Artist or Group, which extend Performer.
An artist is a solo performer. An artist may be in a group and has performed
an album, either solo or as a member of a group.
A group is a collection of artists who collaborate on one or more albums.
Implementations
The implementations are intended for use with the repository, and the repository specifics will
be described in greater detail. Again, the repository tutorial
might make a good introduction.
Storing objects in the repository is facilitated by extending JSQLObject. JSQLObject
provides key management, complex field fetching and collection management. The main useful methods
of JSQLObject include:
getKey(): gets the key of the object. If the object has not been persisted, or has been
removed from repository, it has a null key
isTransient(): returns true if the object is not currently persisted.
update(): persist the object in the repository
remove(): remove the object from the repository
fetchFieldQuiet(String): used from within a descendant to ensure a field is fetched
The JSQLQuery helper class is also often used in the construction of queries which retrieve objects.
The implementation of doc.walkthru.Album for use with the repository. Pieces of interest include:
There's also much more information in the Repository Tutorial.
The list field tracks is declared as holding AlbumTracks. The AlbumTrack is a link between album and track. As tracks may appear
on different albums, the information that ties a Track to an Album is held within AlbumTrack.
The implementation of doc.walkthru.Track for use with the repository.
The abstract implementation of doc.walkthru.Performer for use with the repository. PerformerImpl
serves as the ancestor to the artist and group implementations. It houses the functionality common to performers.
PerformerImpl defines the convenience method, getDiscography(), which fetches all the albums done
by this performer, using a repository query:
JSQLQuery.getObjectByFieldQuery(AlbumImpl.class, "artist", this).getObjects();
The JSQLQuery class contains the methods for querying for objects by type and in conjuction with fields. There is no
need to know the underlying schema when making a query. See the
Repository Tutorial
for more information.
Also of note is the getLinks() method, which returns the links which are associated with this performer (band website, etc). The links are not
marked with @Required and therefor are not fetched and must be fetched when required. Before returning the links, they are
fetched via
fetchFieldQuiet("links")
This method, as defined in the JSQLObject class, resolves the
associated object(s) and populates the given field (be it a list or a solo repository object). This technique can be used to fetch
fields only as required, which improves performance.
The implementation of doc.walkthru.Artist for use with the repository.
The getGroups() method returns all groups of which the artist is a member. This
is accomplished via another repository query:
JSQLQuery.getObjectByFieldQuery(GroupImpl.class, "members", this).getObjects();
This fetches all GroupImpl whose field members contains the
current artist. The repository takes care of all the link resolution, and makes it very
easy and quick to use.
The implementation of doc.walkthru.Group for use with the repository.
Now that the object model is defined, we have something to work with. Lets now create some services, which will provide the interaction
with the object model.