Interview and Book Excerpt: Dan Haywood's Domain-Driven Design Using Naked Objects
Domain-Driven Design Using Naked Objects book, by Dan Haywood, covers the Java application development using Domain-Driven Design techniques and the open-source Java framework Naked Objects (which is now part of the Apache Isis incubator project). In the book, Dan discusses how Java developers can develop and test domain applications by focusing on the business domain model and let the framework take care of the infrastructure related code and configuration elements.
InfoQ spoke with Dan about the book, Naked Objects framework and its recent submission to be part of the Apache project portfolio. We are also making an excerpt (Chapter 13 - Developing Domain Applications; 500 KB PDF) from the book available for our readers.
InfoQ: What type of applications are best suited for using a solution like Naked Objects?
Dan Haywood: For those of your readers who haven't encountered the term, let me first quickly explain that "naked objects" is an architectural pattern where the idea is to automatically expose domain model objects directly within a object-oriented user interface... not just their state (properties and collections) but also their behaviour (what we call actions). You can think of it as analogous to an ORM such as Hibernate; but whereas an ORM reflects the domain model into the persistence layer, naked objects reflects the domain model into the presentation layer.
Naked Objects (capitals) was a Java framework that implemented the naked objects (lower case) pattern, and the topic of my book, Domain Driven Design using Naked Objects. Since then, we've taken the original framework, along with a number of sister projects that I wrote while working on the book, into the Apache Incubator. So, what was originally "Naked Objects" is now Apache Isis.
There's also a commercial product called Naked Objects MVC, which runs as a webapp on the .NET platform and was originally a port of the Java framework. As such, the two products have similar design details, and we continue to borrow ideas from each other. So, when you say "Naked Objects", I'll take it to be "naked objects pattern", of which Apache Isis and Naked Objects MVC are both implementations.
Anyway, to your question. The naked objects pattern requires that your primary consideration is in building an object-oriented domain model, so it's most suitable for enterprise applications that have complex business rules where there's a desire to represent them within such a domain model. The idea - at least during the initial stages - is to build up a domain model quickly, and to get feedback from the domain experts by exploiting the framework's ability to expose that domain model directly within the user interface. A picture tells a thousand words.
But I suspect your question may be a way of asking "are you claiming that the OO UIs generated by naked objects are suitable for all applications?". To answer that, I find it useful to distinguish between two main categories of applications. The first is those applications that are used internally within the organization, by experienced users who are comfortable with the entities within the domain model, and just need an application that imposes as few constraints as possible on how it is used. These are sometimes called sovereign applications. If you're a developer then your IDE is probably the sovereign application you use the most, and how often did you use any of its wizards? And if you use telephone banking then you'll also know how frustrating a sovereign application can be that is too invasive in dictating the workflow... I often find that the poor person on the other end asks me to wait while she goes out of one screen and into another as she checks some detail on my bank account for me. The generic OO UIs generated by naked objects impose no such restrictions, and so are ideal for this sort of application.
There is though a second category of applications, sometimes called transient applications. These are ones used only occasionally or by inexperienced users, typically outside the organization (i.e. your customers), who don't know or care to know the domain model, and just want to be led through the system to accomplish some well-defined goal. My favorite example here is a check-in kiosk at an airport... I just want to get on the plane, and be given the opportunity to choose my seat. I don't care which plane, or even plane type, and I don't care who the pilot is; these are unimportant details to me. For this sort of application a generic OO UIs that exposes lots of the domain is clearly not appropriate. Instead, we want an application that exposes view models rather than entities, and where the UI can be customized. The view model object is responsible for managing the workflow for the user story, exposing just the subset of the domain that is relevant, and hiding the rest of the domain. We find that these view models can be layered on top of the entities once those entities are understood.
Using view model objects is necessary but probably not sufficient for transient applications; we also usually need to customize the UI. Both of the two main implementations of the naked objects pattern (Isis and on .NET) provide viewers that allow the UI to be customized. Isis for its part has two UIs, one that provides a set of taglibs, and one that provides a set of Apache Wicket components. So, using these techniques we can build custom UIs that are applicable also for transient applications.
Putting all the above together, my view is that naked objects is relevant for building any sort of enterprise apps. Its sweet spot is in building sovereign applications with complex business domains, but you can readily target it for transient applications also.
InfoQ: What are the limitations of Naked Objects framework?
D. H.: It's certainly true that naked objects is an opinionated pattern, so if you don't agree with some of its opinions then you're going to find it limiting in some way or another.
The first of these is that everything that the user wants to interact with has to be an object of some sort. As I've already explained, for sovereign applications, these are likely to be the persisted domain entities, but for a transient application, the object may be a view model to be support a particular workflow, and which may or may not be persisted. I don't consider that much of a limitation, but it's worth noting that other architectures (e.g. Spring Web Flow or Struts) would put the responsibility for tracking workflow not into an object but into some sort of declarative XML markup or even just in the interplay between controllers and views.
A slightly more subtle consequence of the above though is that integration of different technologies happens through the domain objects, rather than in front of them through application-layer or UI layer mashups. For example, supposing that we wanted to have an SMS sent out to confirm a checkout. If you were writing the UI and application service layer yourself, you might choose to have the application layer make the call to the SMS service, judging it to be a coordination responsibility. With naked objects, though, you don't get the chance to write any application layer code, and so this would be done by having the domain object call out to the SMS service. The SMS service would be defined by an interface, and the implementation would be injected into the domain object by the framework. I know that not everyone is necessarily comfortable about injecting domain services into entities; I guess all I can say is that we've used it on some big implementations and it works for us.
Another area where naked objects is going to feel different - and perhaps limiting to some - is that it pushes some responsibilities onto the domain objects that otherwise might sit in other layers. For example, a placeOrder action on a Customer can have a supporting validatePlaceOrder method that the framework will use to validate the action's arguments prior to invoking the action itself. It's also possible to have disablePlaceOrder method, which if returning non-null will cause the action to be greyed out the action in the UI. For example, a blacklisted Customer might not allow any orders to be placed, and would indicate this through the disable method. Some might consider this as a misplaced presentation concern. However, the Customer isn't greying out the UI itself; the disable method is merely a convention by which the presentation layer can interrogate the entity.
Something else we hear sometimes is that naked objects is only really suitable for CRUD style applications. I must admit that this criticism does irk me, because although it’s true that naked objects frameworks automatically expose object state, they also expose object's behaviour. What I mean by this is that every public method that is not a property or a collection is taken to be an action and will rendered by the UI as a button or a link. Indeed, we sometimes like to talk of behaviourally complete domain objects; it's the very antithesis of the anaemic domain model anti-pattern.
All the above notwithstanding, probably the biggest impediment to going out and using naked objects right now is that it's a small community and as such the codebase, at least on the Java side, is still relatively new. Part of the reason for that is because I wrote a lot of it while working on the book; at any rate that's one of the reasons we're in the Apache incubator, hoping to build up both the size of the user community and contributors. On the .NET side, the framework integrates only with Microsoft technologies (ASP.NET MVC and Entity Framework), and as a result it's rather more mature. But if the relative "newness" is a turn-off, note that you can still use naked objects to prototype your domain model, because they are just POJOs after all. Indeed, this is a topic I cover explicitly in my book: using naked objects for prototyping but deploying on some other framework.
InfoQ: How does Naked Objects framework support Service Oriented Architecture (SOA) based applications where an enterprise Service component is consumed by several different web applications and other clients?
D. H.: I can answer this both in terms of a naked objects application consuming SOA services, or in providing services.
For consuming SOA services, the answer is easy enough: wrap the SOA service in a domain service interface, and then register the implementation with the framework so that the service is injected into each domain object. That interaction can be either synchronous or asynchronous; there's nothing to prevent the domain object publishing an event to be picked up by some other component out there on your enterprise service bus.
For providing SOA services, at least on Apache Isis, there are several different viewers available, and one of these exposes the domain objects as a RESTful layer. We map objects and object members to the standard HTTP verbs, e.g. so that a GET on an object returns an object representation, a PUT on an object's property will modify the state, or a POST on an object's actions will invoke the action. Right now the representation is in terms of XHTML, which has the nice side effect that the representation can actually be viewed directly from a web browser. We do intend to also provide a JSON representation, but that's still on the roadmap for now.
InfoQ: Naked Objects is currently under Apache incubator status as Apache Isis project. Can you share with us what are the next steps and the timeline for the Isis project?
D. H.: Well, we've migrated all the code over for both the original Naked Objects framework and my sister projects, and have updated all the package names and license headers etc. We also have our site up and are publishing into the Apache snapshot repo. We're currently working towards putting our first 0.1 release out; the main things still to do is to get our documentation all up to date. We also have a quickstart Maven archetype which you can use to get you up and running quickly; full details are on the site.
In terms of timeline, well, we'll be in the Apache incubator until such time as the Isis has proven to have a self-sustaining community. Realistically, I'm expecting this to take 18 months to 2 years, but it'll take as long as it needs to take. Although the community is small for now, those of us involved deeply believe in the approach, and we'll just keep plugging away till we get there. Certainly the move to go into Apache is starting to pay some dividends; there are 4 or 5 people who are now contributing who weren't involved in the community before we were in Apache.
InfoQ: What is the future road map of the project?
D. H.: Our proposal to join the incubator is online, and that captured the thoughts we had at that point in time. A general theme is in the ongoing development of the various viewers; I'm keen to carry on developing my viewer based on Wicket, as well as add JSON support to the RESTful viewer. Meanwhile Rob Matthews (the original architect of Naked Objects and still heavily involved) continues to develop his taglib-based viewer, Scimpi, and there are other contributors who have expressed interest in developing similar viewers using JSF/Facelets, Tapestry and on Android. There's also an M.Sc. student whose thesis project is a RESTful client implemented in JavaFX. I'm hopeful that his university will allow him to donate his project, once completed, to Isis.
Isis has a pluggable architecture, as I've indicated, and there are about five major APIs (and numerous more fine-grained APIs) that can be developed. Probably the most significant of these is the object store (persistence) API. One of my sister projects was an implementation to persist an RDBMS using Hibernate; however Hibernate's license is not compatible with Apache's, so I want to rework that. In fact, one proposal we've had is to re-implement using JDO 3.0/DataNucleus, which would allow us to cover a lot of persistence technologies in one fell swoop. I'm all for deleting redundant code if we can!
Another objective during incubation is to make Isis more easily bootstrappable and embeddable, and for that I'm hoping we'll get a chance to expose the Isis components via JSR-299 (Contexts and Dependency Injection). For example, it should be easy to take just the Isis metamodel component and use it within your own applications, e.g. to drive the rendering of domain objects within custom UI code.
One other area we might see work is in support for other JVM languages. Isis already supports Groovy as well as Java, and the way that Isis builds up its metamodel means that supporting other languages (Scala, Fantom, Go) ought to be pretty straightforward.
I could carry on listing lots of ideas and directions for Isis. Ultimately, though, Apache Isis' roadmap depends on where its community wants to take it; so any of the above might change as we progress through to graduation.
You can find more information on Isis on the project website or by subscribing to the mailing list. If anyone is interested in Naked Objects MVC, on .NET, there are screencasts and a free download at their website.
About the Book Author
Dan Haywood is a freelance consultant and trainer specializing in domain-driven design and agile development on Java and .NET. With 20 years building enterprise systems, he's an advocate of the naked objects pattern, and provides technical advice on the Irish Government's strategic naked objects system. In Sept 2010 he took the lead in moving the original Naked Objects Framework into the Apache incubator, resulting in Apache Isis. He’s now busy building up Isis' community. Dan has authored several books, the most recent being "Domain Driven Design using Naked Objects".
90% of my learnings in modeling complex domain applications
I am working for more than 10 years in the area of implementing complex business domain applications. From time to time I find a book like Eric Evans DDD book that brings some more light into the subject. Your book summarizes most of them already!
Starting from DomainDrivenDesign itself over BehaviourDrivenDevelopment over Hexagonal Architecture over domain patterns, ... Up to now I did not know about a signle reference that I could give to my team members to explain to them the full picture.
For me the core principle for good design (does not matter if OO or functional programming) is to "avoid update anomalies" (I've explained what I mean in more detail in an answer to a blog post here: blog.johanneslink.net/2009/03/06/a-unified-theo...). Avoiding update anomalies means to avoid redundancy and in today's typical multi layered applications there is A LOT of redundancy! between the UI and the persistence.
Some time ago I tried to explain on the JSR 303 forum the need to extend validation to a level that it can be used for introspection on the UI:
JSR 303 has a too narrow scope, so that it is only useful for very simple validations and for the integration of the domain objects to the database. It leaves the space between the UI and the domain completely empty!
The Naked Objects framework seems to close the gap. I am very happy to see that.
The only remaining question I have is if the "meta information" should live in the domain objects themselves or if it should be separated out into other meta data formats (e.g. annotations, separate xml, rule engine rules, ...). Naked Objects seems to favour the pure OO approach and depend on naming conventions to make introspection possible. I'll have to think about that aspect for a bit longer.
I recommend the book to any developer of (not only) complex domain applications! I only fear that only people who already were bitten by the pit falls of complex domain applications will really recognise all of the value the book has to provide.
Re: 90% of my learnings in modeling complex domain applications
- naked objects specifications and "filter early":
is there a way to describe the naked objects specifications in a "language neutral" way, so that they could be used for DB queries, too? I don't know too much about .NET, but I believe that MS LINQ does exactly that.
Some of the possible options for Java are enumerated here:
Does Naked Objects already allow for "filter early" or is it planned? I hate OO applications that bring the whole database into memory in order to filter across the object graph instead of letting the DB do the job.
Re: 90% of my learnings in modeling complex domain applications
Glad that you've found the book and article useful, thanks for taking the time to post a comment.
Regarding your question on "meta information", Naked Objects (or rather, Apache Isis as it is now on the Java platform) supports a pluggable architecture (its FacetFactory API) so is able to pick up metadata from anywhere, not just from the java.lang.Class's themselves. For example, we have an example where we pick up the names of class members from a simple filename; and the i18n support if enabled picks up names of class members from ResourceBundles. You could, if you wanted, write your own FacetFactory's to pick up metadata from a database, or from XML, or from an LDAP store, or anywhere else. If you'd like to post a question on our mailing list (mailto:email@example.com) then I'll go into more detail for you there.
Re: 90% of my learnings in modeling complex domain applications
First, you can just hide the detail behind a repository, and require that the repository implementation (which is dependent on the configured objectstore) to "do the right thing". For example, in the case of the JPA-based objectstore, one would typically be writing repository implementations that invoke named queries, or just use JPAQL or the JPA persistence criteria.
Second, we also provide a org.apache.isis.applib.query.Query interface which represents the query. Domain programmers can optionally use this, and it will be passed through to the backend object store. Its the responsibility of that object store to "do the right thing"; in the case of the JPA object store for example it is used to invoke a JPA named query.
But as you point out, there's nothing as pretty as LINQ for the Java platform, so the means by which this is done will depend on which objectstore you've configured as the persistence layer.
Interestingly, on the (commercial) .NET version of Naked Objects where LINQ is supported, it's actually possible to the same repository implementation independent of configured object store; the "filter early" is then done by the configured LINQ provider (eg LINQ for EF). And given that there's no need for multiple repository implementations, it often becomes feasible to inline the LINQ within the calling domain entities.
Hope that helps, and hope to see you on the isis-dev mailing list!
Domain-based Transaction Logic
Our company is also focused on this area, specifically the business logic. You can define "logic classes" that specify declarative rules applied on commit that automate multi-table transaction logic. Our website shows a typical example where 5 rules replace 500 lines of Java. Unlike Rete, we are optimized for aggregate (sums and counts), and provide automatic enforcement by plugging into Hibernate/JPA events. I think this can add significant value to DDD and Isis.