Java Development News:
Naked Objects 3.0: Integration with Hibernate
By Naked Objects Group
01 Sep 2006 | TheServerSide.com
The Naked Objects group has announced the Milestone 1 release of Naked Objects version 3.0, downloadable from sourceforge.net/projects/nakedobjects.
Many people first heard about Naked Objects from our first series of articles on TheServerSide almost three years ago. If the term 'Naked Objects' still means nothing to you, those articles provide a good summary of the concept and of its benefits.
Three years ago, the Naked Objects framework (version 1) was essentially a prototyping tool: By auto-generating an object-oriented user interface directly from the domain object definitions (using reflection) it facilitated the creation of prototype business applications. As we had already demonstrated by then, using this tool encouraged cleaner object designs, which in turn resulted in more agile systems.
The framework has moved on dramatically in the last three years. Version 2, which we started to develop in January 2004, was intended to be used not just as a prototyping tool, but as part of an enterprise architecture for delivering real applications.
In September 2004, the Department of Social and Family Affairs (DSFA) in Ireland (roughly equivalent to the Social Security Administration in the US, or the Department for Work and Pensions in the UK) took the bold decision to build its new enterprise architecture around the Naked Objects framework. In May 2006 it went live with the first of a new generation of large-scale business applications based on this new architecture: A replacement for the state Pensions Administration systems. This system is now intensively used by more than a 100 clerical and management staff, generating more than 250,000 transactions per day. Since May 2006 it has issued more than €1bn in pension entitlements - a mission critical system by any standards. A second set of applications went live at the end of July and by the end of this year there will be more than 200 users and several more applications. Several of these applications support very complex business operations.
The benefits of using the Naked Objects approach have visibility at the most senior management levels. One of the most concrete manifestations of this is in the latest application: A replacement for the Child Benefit Administration system. The previous Child Benefit system, written just five years ago, ran to more than 50,000 lines of business code. A year ago, we claimed to the DSFA management that by re-using the business object model we had created for the Pensions system it should be possible to create the brand new Child Benefit system using less than 1000 lines of custom code. When functional development was completed on July 31st, the final tally was 957 lines. To put this into perspective, most so-called 're-use' initiatives (within organizations that develop their own bespoke applications that is - as distinct from within IT suppliers) would consider 10% re-use of business code to be a success. By any measure the new Child Benefit system shows 98% re-use - and that is just of business code; this does not take into account the 100% re-use of common technical infrastructure. Two things have made this possible. The first is that there is no application-specific user interface code - the UI for both systems is created 100% automatically from the business object definitions. The second is that the Naked Objects approach encourages very good object-oriented design, specifically, very high levels of polymorphism. (Simply put: When the only thing the user can interact with are the domain objects themselves, those domain objects had better be a very good representation of the business domain and they had better be behaviorally complete).
To paint a realistic picture, it must also be stated that the challenge of creating the new technical architecture around the Naked Objects framework (version 2.0) was by no means straightforward. The contractor responsible (BearingPoint Ireland) had to undertake a lot of technical integration work, building new components where needed to fill in the gaps - including the ability to work with two different (and mutually incompatible) existing database systems.
This experience has led directly to the design and development of Naked Objects version 3. Our aim for version 3 is to allow users to gain all of the advantages that the DSFA has already demonstrated at the business programming level, whilst avoiding almost all of the technical integration work needed for version 2. This is being achieved both by extending the fundamental capabilities of the framework, and by making it interwork with open source solutions that have already solved other parts of the puzzle such as Hibernate. We have also taken the opportunity to introduce other changes that will extend both the richness and the applicability of the Naked Objects approach.
Milestone 1 already demonstrates four of the most significant changes that we will be introducing with version 3:
- A POJO programming model
- Injected resources (Repositories, Factories, Services)
- Integration with Hibernate
- Multiple user interfaces
We will look briefly at each of these in turn.
A POJO programming model
It was always our intent that the domain objects should have minimal dependency on the Naked Objects framework, the idea being that you should write them the same way that you would write them for a more conventional multi-tiered architecture - but without the need to write the other layers. Nevertheless, in previous versions there have been some dependencies: value fields had to use our special 'valueholder' types (such as TextString and WholeNumber); methods intended for access by the user had to be pre-fixed by 'action'; methods for controlling access to fields and other methods made use of 'About' objects; and all domain objects had to return a Title object, for example. Most significantly the domain objects all had to inherit, ultimately, from a AbstractNakedObject class (or provide its own implementation of the fairly complex 'Naked' interface).
By contrast, Version 3 supports a pure POJO programming model. The documentation includes a simple example of how to take an existing Java domain model, coded to JavaBean conventions, and then instantly make this model usable as a prototype application. Any field (as defined by a matching 'get' and 'set' method) will be rendered visible to the user by default. String, int and other basic types are supported. We still provide our own value types such a Date and Money, which offer enhanced functionality, but their use is optional.
Any other public methods will be made available to the user. For example, on the Drag and Drop user interface (discussed below), these will appear as menu actions on the pop-up menu; if the method takes parameters then invoking the action will automatically result in a dialog box. The title of an object (displayed alongside the icon) is now picked up, by default, from the toString() method. (As this can sometimes conflict with other requirements of a toString() method, there is also the option to provide a String title() method instead).
The documentation explains how to then enhance the crude prototype. For example: how to validate values entered by the user into fields or as parameters to actions; how to control the order in which fields or actions are displayed; how to control the conditions under which a field may be modified or an action invoked. In Milestone 1, these 'control' methods have to follow simple naming conventions, in order to relate them to the appropriate method or field. This is not onerous, as it is unlikely that you will already have equivalent methods on your existing domain objects. Nevertheless, with Milestone 2 (which we hope to release within a couple of months) even these conventions may be ignored, by using Java 1.5 annotations to indicate the relationship between methods. Annotations will also then be used to provide various static forms of mark-up - taking over the current role of the fieldOrder() and actionOrder() methods, and also providing a simple way to make fields and methods invisible to the user. The Milestone 1 conventions will still be usable, which is important if Java 1.5 is not an option within your existing architecture.
Injected Resources (Repositories, Factories, Services)
We are fans of Eric Evans' Domain Driven Design and venture to suggest that Naked Objects is a good way to explore and implement many of his ideas. At the DSFA we made extensive use of the Repository pattern; with Naked Objects version 3 we have now brought this right into the framework. The creation of any new instance of a domain class is now delegated to a Factory and the retrieval of existing instances is delegated to a Repository. Factories and Repositories are defined by separate interfaces, although we sometimes find it convenient to implement both interfaces with a single implementation class. From the framework's perspective, Factories, Repositories and Services (which provide an interface to functionality outside the domain model) are all just examples of Resources.
When you start up a Naked Objects application, the icons that you see on the screen now represent Repositories, Factories or (less commonly) Services. In the screenshot below (a simple Expense Claim Processing application) each of the four icons represents a combined Factory and Repository for four of the principle domain classes: Claim, Employee, Item and ExpenseType.
Right clicking on the Claims icons, for example, offers the user methods to create a new Claim or to retrieve existing claims by various search criteria. Visually this is indistinguishable from previous versions of Naked Objects, but previously those icons on the desktop represented the classes themselves, and the menu of actions reflected the class (static) methods on those classes.
One advantage of the Repository pattern is that it encapsulates all the logic to do with persistence. The framework comes with simple implementations of both Factory and Repository that make it very easy to create new objects and retrieve in-memory objects without having to write any dedicated code - this is very useful during prototyping. For an implemented system you will typically want to write dedicated repository methods that make use of the retrieval capabilities of your persistence mechanism - such as SQL queries.
Integration with Hibernate
Naked Objects 3 includes a Hibernate Object Store. There is obvious synergy to be gained from combining Naked Objects with Hibernate: Naked Objects auto-generates a presentation layer from a domain object model; Hibernate maps the domain object model to a relational data model and its corresponding database schema, and within Naked Objects version 3 the Hibernate Object Store can auto-generate this mapping. Combining the two achieves the ultimate goal of a 'single point of definition' for each domain object.
Hibernate is a powerful, high performance object/relational persistence and query service, It is already mature and widely used. It can run stand-alone for testing or simple applications, or within an application server if you wish to take advantage of your server's availability, scalability, connection and transaction management. It is flexible enough to allow you to map your domain object model in a variety of ways, so mapping to an existing database schema is usually straightforward. Hibernate aims to eliminate almost all of the programming tasks associated with persisting objects, and specifically with the need hand-crafted SQL and JDBC calls.
The Hibernate Object Store allows a Naked Objects application to use Hibernate as its persistence layer. Apart from providing the glue that links Naked Objects to Hibernate, the Hibernate Object Store provides other functionality. The Hibernate mapping can be auto-generated, but if required individual classes can be mapped using standard Hibernate mapping files or annotations. The database schema and tables can then be generated from this mapping, so for a new application you can simply define your Naked Objects, and have the Hibernate Object Store take care of the database mapping, and create the tables.
Naked Objects version 3 provides a basic implementation of a Hibernate Object Store, and a simple documented example (which assumes some prior knowledge of Hibernate). For those that have long been interested in Naked Objects but been held back from using it to deliver applications by the lack of a good object store - this provides a powerful capability. But our hope is also that this combination will attract the attention of the much broader community that has already seen the benefits of Hibernate and might therefore see the benefits of extending the idea of auto-mapping upwards into the presentation layer.
In future milestones we intend to extend the capabilities of the Hibernate Object Store, for example to make more use of the Hibernate Query Language for generating online reports and perhaps ultimately to provide a generic implementation of a Hibernate-specific Repository to complement the in-memory generic Repository.
Multiple user interfaces
Prior to version 3, Naked Objects supported just a single style of user interface, of which the latest version is shown below:
Objects are represented as icons, methods as actions on a pop-up menu. Collections can be browsed via the 'tree browser' (shown), or viewed in table form (not shown). This interface makes heavy use of the 'drag and drop' gesture: and for this reason we now label this as the 'DND' user interface.
The second style of user interface is about as far removed from the DND interface as it is possible to imagine: a 'command line interface' or CLI. The following screenshot shows a transcript from a user session using the expenses application shown previously:
The '>' prompt indicates which object is the current focus (or, as with 'Claims', which Resource). Objects may be inspected using a variety of commands such as Field and List. User methods are invoked by the command 'action' or 'act' followed by the method and a list of parameters ('!' means 'use the default parameter value' - in the example above this means use the default Claimant, which will be the user logged on). Typing '?' will give you a list of generic commands, and 'actions' will list the actions available on the object.
At first glance, the CLI might seem like a rather bizarre idea; why have we bothered? The answer is principally for the benefit of blind or sight-impaired users, working with a speech synthesizer. True, most applications running within Windows or a browser can be read by a speech synthesizer, but if you bother to talk to blind users you will learn that they find navigating around a UI designed primarily for sighted users is often very frustrating. And they typically have much stronger memories than the rest of us. For a blind user, a CLI is the most effective style of user interface. (For an excellent exposition of this argument see The Command Line Interface - Ideal For Blind Users by Karl Dahke.) Such users want to be able to type in the minimum of text - so all the commands may be abbreviated, and action names, field names, or object titles all work on sub-string matches. Thus 'act newc...' would have had the same effect as 'action newClaim...'. Blind users also prefer to ask for exactly the information they need than to have to scan through a list to find it. So although there are commands for listing all the fields in an object, or listing all the actions available, once a user has learned the application they are more likely to use it in the 'minimalist' fashion as shown in our example.
You can now deploy any Naked Objects application with either or both of these user interfaces simultaneously. And because both work through reflection, any new object, method or field will automatically be made available in both forms.
So what of the future? We have already mentioned that Milestone 2 will support Java annotations. More generally, with Milestone 2 we intend to make the default Reflector easier to extend or replace (unlike in previous versions, the Reflector is now just another component within the framework). From Milestone 2 it will easier to extend the Reflector to support other programming constructs, for example different value or collection types , or even whole new programming models. When that extensible Reflector is introduced we hope that other parties will run with it and write new extensions (or even whole new Reflectors).
We have now started on a third user interface, which is likely to extend the appeal of Naked Objects considerably: a pure HTML user interface. The idea is that the Naked Objects Framework will return a generic HTML representation of the context, and this will be transformed into a style desired for a particular application or user organization either using existing open source web frameworks or simply with Cascading Style Sheets. We're aiming to provide a first prototype of an HTML UI in Milestone 3.
Naked Objects has always been controversial: Both the idea and the implementation have attracted plenty of criticism. But it has attracted a lot of praise also, and has continued to gain ground. There now exist several frameworks that implement or support what has become known as the 'naked objects pattern,' and we are happy to see this. One of our longer term aims is to define a set of open standards that will allow various of these frameworks to interoperate and therefore to combine their benefits.