lunes, septiembre 19, 2011

The Bell That Rings Inside Your Mind, Is Challenging The Doors Of Time, It’s A Kind Of Magic (A Kind Of Magic - Queen)

During class design we should take decisions about the assignment of responsibilities that will have every class. If we have chosen well, systems tend to be easier to understand, maintain and extend.

Almost all of our projects have a persistence layer, either relational database, document stores, or simply XML files. And typically you will use DAO pattern to implement abstract interface between your business objects and your data store.

In this post but I am going to explain another pattern that can be used instead of DAO pattern. Active record pattern is an architectural pattern that force you to implement CRUD operations on your model  class, hence model class itself is responsible for saving, deleting, loading from database.

There are many strategies to follow to implement this pattern, but for me, the best one is using Aspect Oriented Programming, because we are still maintaining separation of concerns favoring isolated unit testing, and not breaking encapsulation.

Aspect-oriented programming entails breaking down program logic into distinct parts. These parts are known as crosscutting concerns because they "cut across" multiple abstractions in a program. Example of crosscutting concerns can be logging, transaction manager, error manager or splitting large datasets. For people that have worked with aspects not much secret here, to use them you simply create an aspect defining the advice and the pointcut, and your aspect is ready to be executed. 

I guess most of us use aspects-oriented programming as I have described in previous paragraph, but will be fewer that uses ITD (Inter-type Declarations) feature.

Inter-type Declarations provide a way to express crosscutting concerns affecting the structure of modules enabling programmers to declare members of another class.

As we say in my country "bad said but well understood", ITD is a way to declare new components (attributes, methods, annotations) of a class from an aspect.

AspectJ is an aspect-oriented extension for Java. AspectJ supports ITD, and for this reason will be used in this post. Moreover I recommend you install AJDT plugin because it will help you develop aspects and having a quick overview of which Java classes are aspecterized.

If you have not understood what ITD is, don't worry, it is a typical example of concept that is best understood with an example.

Let's start with simple example:

Imagine having to model a car. You would have a car class, with some attributes, for this example three attributes (vin number, miles drived and model) is enough.

It is a POJO with three attributes and their getters and setters.

Now we want to add persistence layer, but in this case we are going to persist our POJOs in a XML file instead of a database. So Car objects should be transformed to XML stream. For this purpose JAXB annotations will be used. For those who don’t know, JAXB allows developers to map Java classes to XML representations and viceversa.

I am sure that first idea that comes to your brain is annotating Car class with @XmlRootElement (annotation to map root element in JAXB). Don’t do that, use aspects. Your first mission is trying to maintain Car file as simple as possible. To add an annotation using ITD, is as simple as:

With @type you are exposing which member is annotated. In this case only class. Other possibilities are @method, @constructor and @field. Then elements pattern that should be annotated, in this case Car class, but you could use any regular expressions like org.alexsotob..*. Finally the annotation.

Next step is using JAXB classes to marshalling/unmarshalling objects. In this example I am using spring-oxm package and briefly you will understand why. Spring-oxm is a part of spring-core that contains classes for dealing with O/X Mapping.

This spring module contains one class for each Xml binding supported. In our case Jaxb2Marshaller is used as marshaller and unmarshaller.

It is possible that you are thinking of creating a service class where you inject Jaxb2Marshaller instance. This service would include two methods (save and load) with Car class as argument or return value. Sorry but, doing this, you are implementing DAO pattern. Let's implement Active Record pattern approach. And as you may suppose, aspectj comes to rescue you to avoid mixing concepts in same source file.

Let's update previous aspect file so all required logic by JAXB will be in same file.

See that apart from annotating Car class we are creating two methods, and an annotated attribute.  Attributes must follow same rule as methods,  <class name> dot (.) and <attribute name>. Note that in this case attribute is transient because should not be bound in XML file.

Last step is configuring marshaller in spring context file.

Not much secret. Now let's code a unit test.

Run junit class and BOOM all red, with an amazing NullPointerException. Marshaller is created in Spring context, but not injected into Car class (Car is not managed by spring container, so is impossible to be injected). And now I suppose you are telling yourself: "I told you a service layer would be better, because it would be managed by Spring and autowired would work perfect.". But wait and see. How about using spring-aspects module? Spring Aspects contains an annotation-driven aspect (@Configurable) allowing dependency injection of any object, whatever is or not controlled by container. So let's apply last two changes and the application will run.

First of all is creating a new aspectj file to annotate Car class as Configurable.

And finally modify spring context file to allow @Configurable annotation.

Adding <context:spring-configured></context:spring-configured> namespace is enough. As a result, any time you instantiate an object (via the "new" keyword), Spring will attempt to perform dependency injection on that object.

Now run unit test again and green will invade your computer :D.

ITD is a really nice solution to design classes with its own responsibilities. It gives you the oportunity of writing maintainable and understandable code, without loosing encapsulation. Of course you should take care of not to have high coupling in aspected classes, and convert them in "God Classes".

Note that implementing same approach but using relational database, it is as simple as changing Jaxb2Marshaller to EntityManager.

I wish you have found this post useful.

Download Full code


7 comentarios:

Anónimo dijo...

Doing this "by hand" is completely impractical/unmaintainable. Use Spring's Roo or equivalent (not aware of any) which does all this for you.  Even then, I think it would be quite difficult to maintain and debug.

Alex dijo...

Hello, thanks for reading this post, I am partially agree and partially disagree with you, I think that doing by hand ITD is not impractical, I know requires more work than coding directly inside the class, but offers a really separation of concerns implementing active record pattern.
And yes I agree with you that Spring Roo does all this for you (with entities), but I also think that it is interesting to know how it works, instead of simply executing a command and nothing more, this post is also focused on teaching purpose.

Thank you again for your comments.

Anónimo dijo...

Hi Alex, thanks for a very interesting read. I can't decide whether I like this a pproach or not. It does look like forcing multiple inheritance into java, and if so, then why not use Scala (which has Traits for this purpose). But out here in the trenches, where multiple unexperienced developers need to mantain real working code, this should be hidden under the hood, so in that sense I agree with the first comment.
Also I missed some reusability in your sample, it does seem like a lot of complexity for solving just the persistence of a single domain object.
Cheers and thanks again.

Unknown dijo...

My idea about this post was not to talk about reusability, but separations of concerns. Maybe at first look you can think that ITD is too complex, but trust me that when you have used, a couple of times, and you have all your model with ITD it really helps you for example avoid thinking about injecting DAO into your persistence manager. It is true that for inexperienced users could be hard, but inexperienced users wants to learn new things, they want to improve their skills so I think this is not a problem.

Thank you very much for reading my blog and merry xmas.

Unknown dijo...

I think this is a very good article with a good example.

Separate of concerns is an important issue. It usually increases maintainability.

To add this code automatically is not necessary (but useful). Many developers add all the JPA stuff by hand, so why not write a few aspects?
Still there are a lot of code generators which could write such aspects easily. That shouldn't be a problem.

Scala is not an option. In most companies one cannot simply switch to a different language, just because it offers a new (interesting) feature.

Personally I recommend this approach more than the DAO pattern.

Unknown dijo...

Hi Thomas, thank you very much for reading my blog. I think you have expressed so well the intention of my post.

Michele Day dijo...

This is the right blog for anyone who wants to find out about this topic. You realize so much its almost hard to argue with you (not that I actually would want…HaHa). You definitely put a new spin on a topic thats been written about for years. Great stuff, just great!
Click Here
Visit Web