Decoration and delegation

Parent Previous Next

The very first example provided a mask to edit a Car object but you couldn't actually do anything with that object. "Doing something" in an object-oriented world means "executing an object's methods", so you must define methods for your domain objects which can be accessed interactively. In general that's very easy to achieve: every public method without parameters becomes a button on a mask. Let's assume we would like to build a kind of simple vehicle fleet management around the Car class. Then we may need a use-case to interactively register a new Car to our fleet. The simplest Naked-Objects-way to achieve that is to add a creation method to the Car class like this:


package quickstart.hello;

public class Car {

   // ... attributes, getters, setters just like before ...


   public void create() {

      // Add the Car to a database

   }    

}


This will perfectly work from a technical point of view and would cause the Car mask to look like this:



Feel yourself encouraged to make things that simple, if it suites your requirements well this way. However, don't make them simpler as they actually are. Let's refine this very simple example to introduce the most important design pattern for gengui-based UIs: Decorator


In most development teams you will probably cause acceptance problems just from the question if an entity may have methods to persist itself. This discussion may be a bit philosophical, but in general you can assume that concentrating too many persistence operations in the domain class itself will soon lead to overcrowding the class with too many responsibilities. So it makes sense to delegate this job.


Another bad small is a clash of names. The Car's method is called create() here which correctly describes the method's purpose, i.e. creating the object in a database. However, the use-case is about "registering" a new Car. Persisting the Car is just one aspect of an operation on a higher level of abstraction.


Considering these points makes it reasonable to separate the concerns:


We don't concentrate on the repository class as this has nothing to do with GUIs any more. The interesting part is the Car registration class which could simply look like this (to be found in directory examples-firststeps/quickstart/create):


package quickstart.create;


public class RegisterNewCar {

   private Car newCar = new Car();


   public Car getNewCar() { return newCar; }

   public void setNewCar(Car newCar) { this.newCar = newCar; }

   

   public void register() {

       // Call the repository's Car creation operation

   }

}


The most important aspect to mention here is that RegisterNewCar does not duplicate the properties of a Car. Instead it provides the Car to register as as structured property which "shines through" when displaying a registration object. So for the first useful UI the Java call should now be


java gengui.infonode.RootFrame quickstart.create.RegisterNewCar


Clicking the Button Register New Car shows a car registration like this:



When thinking of the relationship between Car and RegisterNewCar, don't think in terms of MVC (i.e. RegisterNewCar is not the view of a model class Car). The best way of thinking is in terms of the Decorator pattern [DEC]. RegisterNewCar may put something around the Car like the registration functionality. It may also hide something if necessary or even manipulate certain aspects using the @Decorate annotation which is explained later. But as soon as you realize that the decorating class completely redefines and/or duplicates the structure of the decorated class, you should ask yourself if there is something wrong with the design of the core object.

By the way:

A typical mistake is the missing instanciation of the core object within the decorator. If the core object is null, guess what happens in the UI. Just give it a try and you will see that all Car fields are empty and read-only.


The next chapter will explain how to avoid the creation of poorly initialized Cars by defining more constraints.

Created with the Personal Edition of HelpNDoc: Easily create HTML Help documents