00:21:16 video length
Bio Ramnivas Laddad is an author, speaker, consultant, and trainer specializing in aspect-oriented programming and J2EE. His most recent book, "AspectJ in Action: Practical aspect-oriented programming" (Manning, 2003), has been labeled as the most useful guide to AOP/AspectJ. Ramnivas works for Interface21, providers of Spring.
My name is Ramnivas Laddad and I'm author of AspectJ in Action; I wrote this book a while back, and it introduces you to AOP and AspectJ and also tells you how to apply them in practice. During my day I work as a consultant and also provide training related to AOP and J2 areas, and writing on the book as well.
I'm writing a book on Aspect Oriented Patterns. Here we introduce essentially how to utilize reflecting techniques, with the help of aspect oriented programming.
When you're designing your domain model you should think about your business requirements. So you should think: "What customer class is it representing? What account class is it representing?" So you should think of domain entities and try to model as close to your domain objects and concepts as possible. When you think of other concerns - and those are also business requirements, such as security - you try to model them in Aspects. And there are some other technical concerns as in transaction management, or persistence, or caching, that you try to model separately. For some, if they are cross-cutting concerns you should use Aspect, other suggestions you could have other solutions as well.
If you look at business requirements, you want those to have a nature where "If anything goes here, let's do something". Let's give a concrete an example: business rules and how they are used. Whenever interesting state changes, at least in several interesting places, you fire rule engine, you say "Take a look at the current state and see what other rules need to be fired". And then you take appropriate action. Now if you implement this rule engine manually without using AOP, then you have to repeat that whole process, notifying rule engine, initializing it, firing it, everything on place. What ever the business rule is implementing, is it a crosscutting concern or is it not? If it sounds like a crosscutting concern, that's what you want; you want business rules to have effect, whenever anything changes in your system. This one is one of the prominent examples. But then there are several examples that also have crosscutting nature.
In this one project I'm working on, for example, there is some common data that needs to be pushed into multiple devices. And certain pushing of the data needs to be replicated essentially. It is possible that one device may be offline, or the device may be faulty at this point. So what I want is that whenever I try to push a change, and if the device is not there, then I want to record this change, this being more like a backlog for this particular device, and the next time I'm making an operation, putting another synchronization there, then I want to look at the backlog and go over it and try to push the change.
It is possible that even during the backlog updates I may have another failure. This is a very business specific idea, it's not transaction management; I would declare it as a total failure if anything goes wrong. Here I'm saying "I'm going to deal with this particular situation, in this business, it's a very domain specific manner".
Without Aspects this would have been a really huge amount of code, inconsistency being almost guaranteed, because it's a really complex protocol that you talk through. So every single place you are talking to the device you have to instrument this code and say: "Ok, look at the backlog and try to do this extra updates". In modeling the aspect this is about 20 lines of code, and not only the code is saved, because that's not a critical point anyway, but it is consistent. You can add any operations to your device API and it doesn't matter, this aspect will do the right thing.
In case of shopping carts you are adding and removing things on behalf of the customer. And if the user is doing any operation, you want to check what other promotional items you want to put out there. The user browses things, the user adds items, the user is checking its price, but you can take these things and fire your rules, and that will give you an idea of what other things you should put there. Or a more interesting situation will be in an Ajax based application, and as the user is browsing, you try to capture the data and then you use it to do some promotional things, or offer different pricing, based on the user's interests. You can have all those things at the backend, an aspect that is using all those things, understanding it and maybe by using business rules engine, if it is appropriate, and then giving it the expected functionality.
Both approaches are valid; it all depends on what kinds of processes are used internally. For example, you may not want to over design with your Aspects either so you say "Ok, here is how I want to deal with exception handling in this particular class". Your first instinct may not tell you to use an aspect, so my suggestion is to go ahead and do those try catch blocks, and at some point you will realize something is not right, or you may look at the code and say "that doesn't seem quite right, maybe we should put it in aspect". So essentially you're mining aspects from your existing code. That's an extremely valid approach. In other cases, during design for example, you look at a requirement of security, and at that time it's best to go with aspects from the get-go and say "security will be taken care of by a few Aspects". So it all depends on the specific situation, either approach is valid.
I will change that question slightly and say "How do you deal with crosscutting concerns in modeling?" Let's look at how we do it currently without Aspects. So how do we represent security as an entity in modeling? Or how do we represent transactions or error handling? I don't see a system doing that with crosscutting concerns, as far as modeling is concerned. In a sense you do have an entity called transaction manager, or security manager, and then you will use those services from all these objects. But if you have too many objects using transaction manager, it doesn't make sense that you have a relationship between the object and the transaction manager. So you leave it out there. You take almost the same approach when you deal with Aspects.
Aspects have two personalities: there's an object personality - aspects behave like any other object, it has methods, it has a behavior, it has state. But it also has another nature, another personality, the crosscutting personality. So in modeling, as far as the object personality is concerned, just use normal modeling techniques. That means you will have a transaction management aspect with stated behavior and whereas crosscutting is concerned I just use annotations. I just put an annotation saying "This aspect applies to this point cut". One small thing I do is use a stereotype aspect for my Aspects that makes it clear that this is an aspect, not just an object.
Basically try not to over-model things. In a sense the problem of crosscutting concern is not just an implementation problem; it's a design and modeling problem. We have now answers in implementation, AspectJ, Spring AOP, JBoss AOP, essentially all the AOP implementations. We do not have as clear answers in design or in the modeling space. It should be clear that this is usual with Aspects, how you are going to model crosscutting concerns is not a problem that is actually dealt with in any systematic fashion. There are ideas mainly in those areas like UML that talk about how to model in the presence of Aspects. But there is no tool support for those ideas. It will all emerge, but right now I would say don't over model, just look at your aspect, look the object personality of it, and model that portion. If you really want to do certain behavioral modeling, use sequence diagram with annotations and say "Ok, when I'm going to make this call, aspect will get fired". But you have to make sure you are not overdoing it.
When somebody says Aspects are all about policies, there are actually 2 kind of things they mean, I'm never sure what they are and I'm always trying to clarify it. The first is related to security policies. What is the security policy of this application. That's the business requirements based policy in a sense. The second kinds of policies are policy enforcements, architectural constraints policies, such as certain things should not be called from certain classes.
I will give you an example that was my first serious aspect that really helped me solve some problems. I was working on a Swing based project and used to get some intermittent problems, you suspected that it was some threading related issues. You might be aware that Swing is a single-threaded library, that means you are not supposed to call Swing components from any thread other than dispatcher thread. So we had this problem which showed up only once in a while, and for some reason whenever we gave it to customers that problem would show up for sure. We did a couple reviews, and spotted some points, but not really anything that helped us. So I wrote a small aspect that said: "Make sure that whenever a UI component is updated the caller thread is in the dispatch thread, if it is not then report it". So we compiled our code with this aspect, and just used that code in the jar file for a few days, just normal usage. And at the end of the day we got a lot of output that told us all the places the violation was happening (and the callstacks). So we knew exactly why it happened. And that time if I remember correctly it was AspectJ .8 version. So obviously I did not want to put that code in production, it was not the right thing to do. So I basically implemented the correct code manually so Aspects helped me to enforce the policy of single threaded rule.
Other Aspects that are going under the same categories are EJB enforcements, making sure that EJBs are not violating their policies such as "do not use thread stuff from within EJB do not do weird things from within from within EJB, do not use non final static variables in an EJB. You can do all these things in 2 parts: one is just AspectJ declare error and declare warning mechanisms that basically extend compilers in a crosscutting function, meaning "whenever you find anything that doesn't match, make it an error or a warning". And the second one is that you can monitor it in a live system and say:" whenever you see a violation, report enough information; that way you look at it and you can fix the problem".
The most common way is for creating default implementation of certain interfaces, so if you have going to create a default implementation of that code anyway, you might as well do it through introduction and how that writing the aspect itself, it's almost like a mixin pattern there. The second one is to inject DAO into your domain object. This is basically using Spring and AOP and it says that if I inject DAO then I can use my business objects and no more relying on the service layer anymore then they need to. So in this particular case, I had a user object, user-like entity; and when I initialized it I wanted to make it a part of certain other entities. Whenever a user was created I wanted it to be part of other entities so I needed to have a DAO so that I could get those entities and cleared the relationship I need to. So now I can basically inject DAO using Aspect and say I want to call it and nobody needs to know about it. It's one of those things when you say "DAO is not a business concept but nevertheless is needed by this model so you use it for that kind of purpose.
Pretty big, actually. Design patterns are really there because if you don't use design patterns the problem would be pretty hard to implement. That's why we have design patterns to simplify our implementation. And AOP looks at these design patterns as one of the problems it tries to solve. If you use AOP you don't need some of the design patterns, or you can implement them better using AOP. Let me give you an example: let's look at servlet filters or access handlers, they are essentially implementation of the Chain of Responsibility patterns So before you hit the target do service matter. In a servlet you can apply filters that are doing things like transaction management or session management, security, performance monitoring, that kind of thing.
If you look at this implementation there are several things that you need to get right. First you have to use it in an environment where there is only one or two target methods, because you are telling it to go ahead and do the chain processing, and therefore you need one target matter that you are trying to hit. Second, you need infrastructure, so in the case of a ServletFilter, you need an XML file, you have to parse that XML file, you have to create the filters, and the filters chain, you have to go all over the filters chain and eventually process them. And then you need an implementation of these filters, to do whatever you need to do. Transfer this pattern into Aspects and all you see is one simple aspect with one around advice and now you don't even have the limitation of one target method. If you want to monitor all RMI operations, that's fine, you just change your point cut to say monitor all RMI operations, and then you are monitoring all RMI operations. If you want to monitor web services, just write a point cut and then you are monitoring web services. The idea is that we generalized the pattern; we are now saying that the responsibility is now embedded into Aspect. And Aspects are more powerful because of the point cut language. You don't need one specific target; you can also take leverage the static typing because this aspect can look at the context and know about the static type, and just use it in the implementation. So basically you get a better implementation of the same idea.
Yes, observer patterns are another example of places where Aspects offer better solutions for the same problem. So what are observer patterns? You have a subject, the thing that needs to be observed, and then you have a bunch of observers that have to respond to changes in the subject. It's a good pattern; if you are not using AOP at least use these patterns. The idea is that you don't have to embed the observation logics right in the subject, you can decouple that logic there. And the subject doesn't have to know about the observers, so that say things change, and respond to however you need to respond. But what does this mean in terms of implementation? It's a good and reasonable concept. If I tell you that I'm implementing observer pattern here, you know exactly what I mean. But you look at the implementation, you see the subject that has methods such as addObservers, removeObservers, notifyObservers, getObservers, etc. Then every single place where state changes, you have to notify observers. So that is the implementation on this side, the subject side. On observer side you might look at the notifications, and you might have to filter notification because you may say "I don't care about that particular state being changed". And then you respond to it. If you transfer it to Aspect that uses intertype declarations to inject all these observers into inject all this addObserver removeObserver stuff, and write an advice to say "whenever the state changes, notify observers". And then you can still write your observers in a normal fashion. But then you can go one level up and say "why do I need this entire infrastructure, when I can just advise the methods in my subject and just respond in an aspect". So essentially you can gradually go from first better implementation of the same design pattern, and then even better just using Aspect; at that level you may not even realize that this is observer design pattern.
Concrete example of Business aspects
Re: Concrete example of Business aspects
* User info (matches user, group, container in LDAP)
* Parent/child relationships (one for child, one for parent/container)
* Icon and displayname (there are lots of different variants of this, for different objects)
* File info
* Site/Page/Layout/Portlet and other CMS-related mixins
* Hit counter (also CMS related)
and so on...
That was mixins. Then we also have 130+ interceptor style aspects that maintain various domain rules. Many are related to lifecycle management of aggregated objects (e.g. remove aggregated objects when owning object is removed), and many are related to maintaining various rules (e.g. if an object is added to a container, then the child->parent relationship must be properly updated). These interceptors are all specific to some few number of methods in some specific mixin (i.e. they are not widely applicable to many different mixins and methods), but they ARE heavily reused anyway since the mixins are reused in many domain objects.
We also sometimes use interceptor aspects to define method parameter validation rules, so that these are not hardcoded in the various methods and mixins.
Re: Concrete example of Business aspects
We can even do some cool things like havin articles and news posts announcing them share the same discussion threads.