Aspect Oriented Programming Notes #1: The Concepts

Not just a feature that Spring provides, it’s a model of programming itself. (It’s functional programming)

When you writing in such languages you think of a problem and then you break it down into different functions. Each function accomplishes a particular unit of work. And then a function can call other functions and that’s how they talk to each other.

A single program consists of all these different functions and then you call each other and then when last function ends that’s when the program is complete.

This is the way you would think if you were to write code in a functional programming language. You think of them as different functions.

The problem is here is that if the complex design is involved then you would have a whole lot of function and independencies between functions things could get messy. Some situations you would get a better design if you’d use object oriented programming.

Here is a problem, not all of the task that you would want your program to do can be classified into objects.

Let’s take for example:

You have a common procedure across different objects, taken example of the log message here, so I want a log message method to be run and to be included in three different objects.

What does a log message method do, it prints out a message it’s as simple as that and you want the functionality to be there in all the objects that you are designing in your code. This is not a really good design, because you are repeating yourself by including the same method in different objects.

One way to this is to take that method out and create a separate object for it. Of course you cannot just leave a method floating on its own you would have to include it inside an object, so you would have a log message method inside a new object called the logger object. Object A, B and C would not have that log message method anymore, instead what will happen is whenever a log message need to be called it would reference this logger object and then do a logger.logMessage(). It would either have a dependency so it would create a new logger and then call the method or this might be a static method and then it would call the method directly. It could also be a parent class and then you could inherit the log message functionality into each of your objects that need this method.

Couple of problems here:

1- Too many relationships to the crosscutting objects: Let’s say you’re doing the design and you want to write a diagram that depicts the relationship between different objects and you want to know which object is the really important ones, depending on how they’re connected to other objects you want to know which are the objects that are connected to other objects the maximum.

If you write this diagram for a design like this it’s very likely that the most important object in the most connected object would probably not be your business object will probably be this logger object, because every object that needs a logger has a dependency on this logger object. So, it is not really a good idea to have this kind of a dependency to something that is not really a part of your business problem.

You have too many dependencies to this logger object. And the logger object is not really adding business value. It is just doing a support role. That would be problem one you have too many relationships to this crosscutting objects.

Crosscutting objects: Objects that concern different objects in your problem domain.

2- Code still required in all methods: You still need to have code inside all your methods to make the call, you have removed the logMessage() functionality for example and you have put it in into a logger object. But then you’d still need each of the methods in your business objects to make a call to this logger object’s logMessage() method. You removed the method but you actually have not removed the code that makes the call and you can not removed that because it has to be done, it has to be called and the method has to execute.

3- Cannot all be changed at one: Say you want to have a different logMessage() method and you need to make a change in all these different business objects to call that method itself. Of course we can solve this problem using some more intelligent design, we can have an interface class then we can plug-in the different log implementations but then that is not the case and if you cannot solve the problem by using a common interface for example, you would need to go to each of those classes and you need to make the code change.

Why are there significant problems? Because this whole concept of having a crosscutting object is very common in the software design. You can have this in lot of situations where you have cross-cutting concerns. You have some functionalities that need to be used by different objects and they may not be a part of your problem domain. It could be infrastructure related, security related, these are some of the common crosscutting concerns that you would see in a normal real world application. Almost every major application that’s some kind of logging or the transaction and security. You will implement them depending on your business problem and number of users.

Let’s see how things change with aspect oriented programming:

You would have what are called as aspects. You have removed the common functionality in objects A, B and C instead what you do is you do not create a new class for logging, you create a new aspect for logging. It is actually a special class .

You have a logging aspect class defined separately from your normal classes and objects. Similarly you have many aspects, can have transaction aspect for implement transaction related cross-cutting concerns.

How is this different from having a separate object: After creating these separate aspects what you do is do not reference these aspects in your code, say you want to have some methods in object A, B and C to use the logging aspect in the transaction aspect. If it were an ordinary class what you do is you would have to instantiate an object of the class and then call the methods. You would not do that for aspects. You would define an aspect configuration which tells which objects in which methods these aspects should apply to. So this is what is different from traditional object-oriented programming where you take these common functionality is create a separate class, have objects then reference those objects inside your objects which actually need those functionality instead what you do is you have aspects. And you write configuration which tells which aspect applies to which methods of which classes.

Spring helps us in here, it tells us what aspects are needed for which methods and we will make sure that those methods are also called.

For example, I have a particular set of methods in all these objects and I want a logging aspect method to be called just before each of these methods I’m concerned about runs. Say I have five methods for Object A, four methods for Object C which I want the logging method to run just before those methods execute. What I would do is I had write the configuration over Aspect Configuration and say for all these methods (A, B and C) make sure the logging method runs whenever those methods are called. This is something that I can tell Spring to do and Spring will make sure that the logging method is called just before those methods that have configured here are executed. (Similar to Servlet Filters or Triggers in databases)

They are not configured in the code, separate configuration files and since they’re all running the Spring Container, Spring makes it easy for that to happen, reads this configuration and whenever it senses that those methods are called and those are executed just before those executions happen these configured aspects are executed first by Spring. If you want to make bulk changes you can do that as well just a few lines of Aspect Configuration.

Aspects get their true power by wrapping around your target methods. Lets say you have an execution of target method you can configure an aspect to run before or after your target method, so that if you can figure it this way before-aspect-code will executed and your target method gets executed and then after-aspect-code executed. So you have a lot of flexibility here, you can have different flows of control and you can configure them using aspects.

Steps in AOP:

Write Aspects: We need to identify what are these crosscutting concerns and we need to write them as aspects.

Configure Where The Aspects Apply: We talked about logging, we can select particular methods for which the logging methods runs just before with those methods executes, so that’s the configuration.

About Aliyar Güneş

I’am Aliyar Güneş, a learner and software developer from Istanbul, Turkey. I write C# and Java.
This entry was posted in Spring Framework, Uncategorized, Works and tagged , , . Bookmark the permalink.

Leave a Reply