What follows is a series of views illustrating different aspects of
the system from the perspectives of the user and the developer. This is
not a programming tutorial. Rather, it is an attempt to show the close
correspondence that exists between the two views of a business system
developed with the Naked Objects framework. From these screenshots it is
possible to get a sense of just how easily a user-request can be
translated into the necessary code changes.
Classes
An 'application' consists of nothing more than a set of business
object classes. All user operations take the form of actions invoked
upon an instance of one of those classes or upon the class as a whole.
Any class that could form the start-point of a user activity is shown
in the user's 'Classes' window, shown here on the left of the screen.
1. These are the six business classes
that constitute the prototype reservations system.
2. Right-clicking on any class icon
pops up a menu of class methods, including one to create a new
instance of that class. The generic class methods shown here
require no programming since they are automatically provided by the
framework.
3. Other generic class methods allow
the user to find particular instances or show all instances of that
class.
4. This symbol represents a collection
of objects: in this case, all seven of the cities in the
system.
5. Where there are more instances than
can be shown in one window, the collection would provide methods
(greyed-out here) to page through the objects.
6. The code for this application is all
held in a project folder called
ecs.delivery.
7. There is one Java class
corresponding to each of the business object classes presented to
the user. The label on the user's class icon is (by default)
automatically derived from Java class name. Here
CreditCard has been converted into Credit
Cards. (Irregular plurals must be manually
specified.)
8. Each business object class must
implement the NakedObject interface in order for the
viewing mechanism and/or persistence mechanism to be able to use
it. The easiest way to achieve this is to make each business class
inherit from the AbstractNakedObject class provided
with the framework.
9. The only code in this project that
is not a business class is EcsExploration which is
needed to run the application. Almost everything that this class
needs is provided by the framework's Exploration
class. When the application is deployed this
EcsExploration will be replaced by a simple
configuration file.
Instances
For most business scenarios, the user of the system will be dealing
with individual instances of the business classes, and sometimes with
collections of instances of the same type. By default, an instance uses
the same icon as its class, but has an individual title. It is also
possible to vary the icon according to the identity or the status of
the object.
1. By default, instances use the icon
of their class, but instances have titles to identify them. This
instance is shown collapsed to its icon-only
view.
2. The menu actions shown here provide
different ways to view the object. The viewing options offered will
depend upon the type of object. All the viewing options are created
automatically by the framework.
3. The default view is the 'form' view
shown here.
4. Instances have titles that are usually
derived from one or more of their identifying attributes and/or
their current state
5. Each class is defined by the set of
methods it can fulfil. All these methods deliver specific business
value, and result directly from a user requirement. The underlying
technical methods needed to manage the objects can all be inherited
from the framework and need never be seen by application
developers.
6. Each business class needs a
title method to generate the title that appears
next to the icon. This is normally derived from one or more of its
attributes such as a name, status, or reference
number.
7. The title method must return a
Title . Here the firstName is turned
into a Title object (using an inherited method),
then the lastName is appended to it. The
append method looks after leading and trailing
spaces automatically.
8. CreditCard has a more
complex title method that masks all but the last
five digits of the number.
Fields
Open a view of any object and you will see a set of fields. Some of
these fields contain simple values (such as dates, numbers or text
strings), which the user may be able to enter or edit. Other fields
will contain business objects, shown as icons. Even where an icon
appears inside another object view, that icon still represents a fully
functional object: you can invoke its behaviours in situ or open up a
new view of it.
1. An empty 'value' field.
2. The grey hole indicates that a
City can be dropped in here.
3. This field contains another business
object - a City.
4. Here the user has typed some text into
the value field.
5. If you attempt to drag the right type of
object into a field, (here a City) the drop zone
will flash green. A red flash indicates that the framework will
not let you drop that object there, either because it is the wrong
type or due to some other programmer-specified
rule.
6. Each field in the user view is
determined by the existence of a get method in the
Java class definition. The field name is, by default, a formatted
version of the method name.
7. A business object field will require a
get and a corresponding set
method.
8. Because
setCustomer requires a Customer as a
parameter in the Java file, the framework will automatically
provide the ability for the user to drop a
Customer onto the corresponding field in the user
view, but will disallow objects of other types by flashing the
field red.
9. The framework provides a set of generic
NakedValue classes including
TextString , WholeNumber ,
Date and Money . Such fields require
only a get method because the value object itself
provides the methods for changing its contents.
10. NakedValue objects are
typically initialised within the constructor method for the
business object they are contained in.
11. The resolve method
ensures that a referenced object is only retrieved from secondary
storage when it is actually needed.
12. The objectChanged
method advises anything using that object, such as the viewing
mechanism or persistence mechanism that the object's status has
changed.
Associations
We have just seen how a field can contain a reference to another
business object. Naked Objects can also handle more complex
relationships such as multiple associations, where one object knows
multiple instances of another type, and bi-directional associations,
where two objects both know about each other.
1. The Customer can have
multiple Locations associated with
it.
2. A new Location can be
associated by dropping it onto the grey hole at the bottom of the
collection.
3. Right clicking on any member of this
collection offers the option to Remove
Reference.
4. This is an example of a bi-directional
association. When a Customer is associated with a
Booking, a reference to that
Booking is automatically added to the customer's
list of bookings.
5. A multiple association is managed by an
InternalCollection (provided by the framework) which
can hold only objects of a specified type.
6. A multiple association needs only a
get method to return the
InternalCollection , which then provides its own
methods for accessing the objects it contains.
7. Bi-directional associations (whether
singular or multiple) require the provision of
associate and dissociate
methods.
8. associateBooking on the
Customer first adds the new Booking
to the internal collection of bookings, then sets the
customer field on that Booking to point
to this (customer). In a bi-directional association,
one object manages the association and the other one delegates
responsibility to it.
9. Adding a fieldOrder
method to an object allows us to control the order in which fields
are presented to the user.
Behaviour
The two principal mechanisms by which a user can invoke a business
behaviour are by selecting an action from a pop-up menu on a business
object and by dragging one object onto another. (The latter is not the
same as dragging an object into an empty field inside an object.) It is
also possible to invoke business behaviours at the class level -
through the pop-up menu on that class - or by dragging an instance icon
onto the class icon.
1. At the bottom of the pop-up menu for an
object are the business methods that can be applied to that object.
2. An ellipsis ... following
the menu action indicates that this will return another object as a
new window.
3. Dragging Home, Boston
directly onto Logan Airport, Boston will trigger
the creation of a new Booking that uses those two
locations as Pick Up and Drop Off
respectively. This shortcut is most useful when both locations
show up in a list of frequently-used locations inside a
Customer.
4. The method name
actionReturnBooking is stripped of its
action prefix and reformatted to generate the menu
option Return Booking... automatically. For language
localization it is possible to over-ride this automatic
correspondence. The ellipsis in the menu option reflects the fact
that an object will be returned by this method - in this case a
Booking .
5. createInstance creates
a new instance of the Booking class, called
returnBooking . Just using the simple Java
new keyword instead of createInstance
would not perform all the necessary
initialization.
6. This code swaps the pick-up and drop-off
locations for the return booking.
7. If an action method requires an input
parameter (in this case another Location ) then this
behaviour will not show up on the pop-up menu. Instead, it will be
automatically invoked when the user drops an object of the required
type onto this object.
8. This method, invoked when the user drops
one location onto on another, creates a new Booking
assigning the two locations to the pickUp and
drop-off fields respectively.
9. If another object has invoked this
method then the newly created Booking will be passed
back to it. If the method was invoked by the user from the menu,
then the returned object will automatically show up as a new
window.
10. actionNewBooking is a
static method: it can be invoked from the class icon, not the
instance icons. This method takes a Customer as a
parameter and returns a Booking . In other words,
drop a customer on the Bookings icon and it will
generate a new booking for that customer.
Control
Naked objects empower the user but that does not imply an absence
of controls. Different users will need access to different objects,
different fields within those objects and different behaviours on those
objects. It will also be necessary to enforce certain business rules,
such as preventing an action from being invoked unless the object is in
the right state. In Naked Objects these forms of control are
implemented using about methods and
About objects.
1. Here, the Confirm option is
greyed out, but the user can Check Availability.
2. Check Availability resulted
in the booking's status field changing to Available.
Because of this the user now has the option to Confirm
the booking.
3. The booking now has
Confirmed status.
4. The actionConfirm
method has a corresponding aboutActionConfirm
method that determines whether the former can be accessed. If
access is denied then the viewing mechanism will grey out this menu
option.
5. about methods return
an About object, which contains data about the
availability of a method, class or instance it applies to. Generic
forms of About are provided with the framework.
6. Availability may be determined by
business rules or by user authorisation. The whole determination
could be sub-contracted to an authorisation server.
7. Here,
aboutActionConfirm checks to see if the
Booking object's status field is set to
Available . If so, ActionConfirm will be
made accessible to the user.
8. Here, a reason is provided for the
unavailability of the method. In the current version of the
framework, this message shows up in the system log window. In a
future release better use will be made of this capability, perhaps
in the form of optional balloon help.
|