Sponsored Links


Resources

.NET Research Library
Get .NET related white papers, case studies and webcasts

Naked Objects for .NETNaked Objects for .NETNaked Objects for .NET Discuss DiscussDiscuss Printer friendly Printer friendlyPrinter friendly
Naked Objects for .NET

March 10, 2004

Since it was launched in November 2002, the Naked Objects framework has been attracting a great deal of attention in the Java community. Now a .NET version has just been released.

The idea of Naked Objects is that business applications should be built from 'behaviourally complete' domain objects, which are then exposed directly to the user. The screenshot below shows a simple demonstration application running under .NET. You can download a freestanding executable version of this demo from www.nakedobjects.org, and the source code for the demo is included with the .NET framework download.

(Click to see larger image)


The demo application is a simplified booking system for a limousine service. (It was actually written for a demonstration to one of the largest US limo-service companies after one of the authors had a frustrating customer service experience that clearly resulted from the poor design of their existing reservations system!) On the left hand side of the screen you can see icons representing six classes of business object: Booking, City, Location, CreditCard, Customer and Telephone. Right clicking on any of these class icons gives you the options of creating a new instance of that class, or retrieving existing instances. Open elsewhere on the desktop are icons representing individual instances, some of which have been 'opened' to show their data attributes and associations to other objects.. Right clicking on an instance icon (in any context) will give a pop-up menu of actions that can be applied to that object.

All user actions thus consist of creating instances or retrieving existing ones, editing the data fields, forming associations by dragging objects into fields on other objects, or initiating an action on a specific object (or collection of objects - the icon with four red blobs is a collection). There are no top-level menus, no dialog boxes, or the other paraphernalia of a conventional user interface. This approach comes as quite a shock to most developers, many of whom initially retort that such a restricted approach could not possibly be used for real systems. We have very strong evidence to the contrary: not only has it been used for substantial real systems, but the users themselves have reacted very positively. For although such an application will at first seem slightly unfamiliar, users very quickly learn the 'noun-verb' style of interaction (conventional systems are typically 'verb-noun') and come to appreciate the far greater degree of control or 'expressiveness' that this style of interface affords. We'll hopefully get an opportunity to present that evidence, and some supporting analysis, in a later article.

For now, we'd like to concentrate just on the developer perspective. For what is remarkable about the demo application shown above is that writing it consisted of writing just six classes in C# : one for each of the business object classes shown on screen. (If you examine the source code you will see a seventh class called an 'exploration', but this contains very little code and serves merely to initiate the application). The objects could also be written in VB.NET or J#, but C# will be used throughout this article.

Each of these classes is complete: it contains the code to define all the attributes and associations for that class, and all the business methods that apply to it. The important point is that creating that application did not involve writing one single line of code that had anything to do with the user interface.

Instead, these business object classes are compiled and linked with the Naked Objects framework (distributed as a .dll). At runtime, the framework uses reflection to inspect the attributes, associations and methods of each class and renders these in the form shown to the user. All this happens dynamically: there is no code generation going on. To understand this better it is useful to compare some snippets of code from the Booking class, with the representation of a Booking object on the screenshot above. First look at the class definition:

public class Booking:AbstractNakedObject

each of the six classes inherits from the AbstractNakedObject class provided by the framework (If inheritance is not feasible then you can choose to implement the NakedObject interface instead, but this involves more work.). The next snippet:

virtual public TextString Status
		{
			get
			{
				return status;
			}
		}

defines one of the 'value fields'. TextString is a class provided by the framework. It broadly mimics the functionality of the C# System.String class, but provides additional methods for use by the framework. There are similar value classes for Date, Money, WholeNumber etc.

At runtime, if the framework sees one of these value properties it will render it to the user in the form of an editable text field. The label on the field will, by default, simply be the name of the property ('Status'). (It is possible to over-ride this, but it is good practice to use the same name if possible). Some of the values have their own dedicated viewers: for example a Logical value (equivalent to the C# bool) will be rendered as a checkbox.

On the value fields, no 'set' is needed because the value object contain their own methods for editing the value. However, a setter is needed where the field contains a reference object then both a get and set are needed, as in this defintion for the customer field:

virtual public Customer Customer
		{
			get
			{
				resolve(customer);
				return customer;
			}
			set
			{
				customer = value;
				objectChanged();
			}

		}

At runtime, this code will be rendered as a field that can hold a Customer object (in the form of an icon). If the field is empty it will show as a grey 'hole'. When a Customer object is dragged over the field the grey hold will flash green to indicate that it may be dropped there. If, however, the object is of a different type the field will flash red and prevent the association. The resolve() and objectChanged() methods are provided by the framework: resolve() ensures that the customer object has been retrieved from storage (the framework adopts a lazy loading strategy); objectChanged() notifies the viewing mechanism to update any views of the object, and notifies the object store to persist the new reference. (The object store is a component within the Naked Objects framework and several alternative object store components are becoming available).

Next, let's look at a typical business method. On the pop-up menu in the screenshot above, there is a Return Booking... method, which creates a booking for the return journey (i.e. with the same customer details but the pick-up and drop-off locations reversed). The code representing this method is:

public virtual Booking actionReturnBooking() {
  Booking returnBooking = (Booking)
createInstance("ecs.delivery.Booking");
  returnBooking.associateCustomer(Customer);
  returnBooking.PickUp = DropOff;
  returnBooking.DropOff = PickUp;
  returnBooking.PaymentMethod = PaymentMethod;
  returnBooking.ContactTelephone = ContactTelephone;
  return returnBooking;
}

Any method with the action prefix will, by default, be made available to the user: the framework just strips out the prefix and formats the remainder of the method name appropriately. (Again this can be over-ridden if necessary, but preserving the commonality is good practice). The method body is straightforward: createInstance is used in place of a simple 'new' in order to ensure that the new Booking is made persistent. The method returns the newly-created Booking object.

If the method has been called by the user (i.e. from the pop-up menu) then the returned object will be manifest as a new window on the screen. (The auotmatically-generated '...' following the menu option indicates that something will returned). However, it is important to understand that 'actionMethods' are not written specifically for the user: they are merely methods on the object and may be called by other objects or an external system.

In the pop-up menu on the screenshot, certain of the methods were greyed-out, indicating that they are unavailable. This is controlled in Naked Objects through the optional addition of 'about' methods. Here is the about method that corresponds to the actionReturnBooking method:

public virtual About aboutActionReturnBooking() {
  ProgrammableAbout c = new ProgrammableAbout();
  c.setDescription("Creates a new Booking based on the current
booking.  The new booking has the pick up and drop
off locations reversed.");
  c.makeAvailableOnCondition(Status.isSameAs("Confirmed"), "Can only
create a return based on a confirmed booking");
  c.makeAvailableOnCondition(PickUp != null, "Pick Up location
required");
  c.makeAvailableOnCondition(DropOff != null, "Drop Off location
required");
  return c;
}

The about method returns an About object (another framework class), which informs the viewing mechanism of that methods availability based on a set of specific conditions - three of them in this example. Notice that each of the conditions also includes a literal string that specifies the condition in plain English. At runtime, if the user holds the mouse over a greyed-out menu option, this literal string appears in the status line at the bottom of the screen.

This illustrates a deep philosophy of the Naked Objects user interface: prevent the user from performing an illegal action, but make it easy for the user to see why it is being prevented. This is in marked contrast to the appalling practice, made commonplace by browser-based interfaces, of allowing the user to initiate any action and then popping up an intrusive message window telling them that the action they just attempted was illegal!

About methods can be applied to fields as well as actionMethods, rendering those fields unmodifiable, or invisible. These controls may be based on the state of the object, on specific business conditions, on the user's identity or, more commonly, on the roles that the user fulfills. Thus, although the Naked Objects approach provides the user with more freedom or expressiveness than a conventional user interface, it can provide very hard forms of control where these are strictly necessary.

The purpose of this article is just to introduce the concept of Naked Objects to the .NET community. Some of the benefits of the approach are self-evident: speed of development and a common language between developers and users. Other are less obvious at the outset, but just as powerful. You can read a much more thorough explanation of the approach, the rationale behind it, and the benefits that it delivers in the Naked Objects book, which is available from Amazon or can be read freely on-line on our website: www.nakedobjects.org. But the best way to understand it is to download the example and start modifying it

Authors

Richard Pawson conceived ths idea of Naked Objects in the early 1990s, although it was many years before it became a viable proposition. It formed the basis of his PhD thesis: recently completed but still awaiting examination. Richard was 14 years with CSC (www.csc.com), six of them as Director of Research where he specialised in researching best practices in object-oriented techniques and agile software development - before leaving to found the Naked Objects Group. His career in IT started in 1977 working for the calculator company Commodore, when he helped to launch the first personal computers into Europe. He is a follower, and friend, of the architectural guru Christopher Alexander and designed his own house using 43 of Alexander's now famous 'patterns'. He can be contacted via www.nakedobjects.org.
Robert Matthews is the originator and principal author of the open-source Naked Objects framework, which he started to develop in 1999. Robert co-authored the book 'Naked Objects' with Richard Pawson, which can be ordered from Amazon, or read for free on the naked objects website. Robert has been developing software for 16 years. He can be contacted via www.nakedobjects.org.
Dan Haywood is currently a freelance software developer, analyst and trainer with more than fifteen years' professional experience at Accenture, Sybase and others. He is co-author with Andy Carmichael of the book 'Better Software Faster'. Dan joined the Naked Objects community in 2002 and has become one of its most active contributors. Dan was responsible for the initial porting of Naked Objects onto the .NET platform. He can be contacted via www.haywood-associates.co.uk

News | Blogs | Discussions | Tech talks | White Papers | Downloads | Articles | Media kit | About
All Content Copyright ©2007 TheServerSide Privacy Policy
Site Map