Last week I was involved in a teleconference with Ramnivas Laddad - a leading proponent of Aspect Oriented Programming and author of the excellent book ‘AspectJ in Action’. We were discussing (amongst other things) the potential synergy between Naked Objects and AOP.
We’ve been reluctant to tie Naked Objects specifically to AOP, because that might narrow the community to which it might appeal. But it seems to me that for anyone who already understands and uses AOP (specifically AspectJ) then there are some very easy advantages to be gained. Three immediately sprang to mind:
1) Use an aspect to add the required resolve() and objectChanged() calls within properties at runtime.
2) In a Naked Objects application it is not safe to use a simple constructor within your code (e.g. Customer newCust = new Customer(); ) because then the application container does not know about the new instance and can’t look after its persistence automatically. So you need to write something like:
Customer newCust = (Customer) container.newTransientInstance(Customer.class);
where ‘container’ refers to an injected instance of the application container, which Naked Objects can inject automatically. Again, the need for this could easily be eliminated by an aspect that defines a point cut at instantiation.
3) In Naked Objects 3.0 a method (such as emailCustomer(String message)) may have a corresponding validateEmailCustomer(String message) and/or disableEmailCustomer() method. These will be called automatically by the framework to determine whether the user should be able to invoke the action. However, these constraints are not automatically enforced if the emailCustomer() method is called programmatically i.e. from inside another action.
If you do not trust programmers to invoke your domain methods safely, then a good practice would be to call the validate.. and/or disable.. methods from inside the emailCustomer() method and throw an exception if any of them failed their tests.
Using an aspect, this capability could be added automatically.
Incidentally, we are often asked why Naked Objects requires the validation and/or disablement rules to be extracted into separate methods - why not just write them inside the emailCustomer() method and throw an exception if they fail, trapping the exception to present a message to the user. Well there are two reasons. The first is that we believe that you should only use an exception to handle a situation that ought not to occur, such as a technical failure or a programming error. Whereas a user attempting to invoke a method without valid parameters) is something that can and will occur often.
Secondly, and more importantly, if the rule was enforced only inside the method, then it would not be possible to find out if the constraints have been met without attempting to invoke the method. By separating out the logic, we are able, for example, to keep the ‘OK’ button on a dialog box greyed-out until the user has provided a valid set of parameters.
The reason why some people find it hard to see this value, is that in a conventionally-architected system, validation and availability rules are typically implemented within the Presentation and/or Controller layers, and then many of the same rules are implemented all over again within the domain objects, and sometimes again within the database design. We believe that that business logic should be implemented in one place only: on the domain objects. In Naked Objects, the rules for disabling a method, or validating the parameters, work whichever style of user interface you create from those domain objects.
Personally, I’ve never yet written an Aspect – something I intend to rectify in the next few weeks and try out these ideas. (Or at least the first two - the last one looks a bit more tricky to program!). But if there’s anyone out there who is already fluent in AspectJ and would like to try out the ideas first - let us know how you get on, and we’ll post it on this blog.