Friday, July 4, 2008

Aspect Oriented Programming

ASPECT ORIENTED PROGRAMMING

(AOP)

Introduction:

In a perfect world, there would be no such thing as software rework. We would get the object model right the first time. The waterfall approach to development would work just fine. But alas, we don't live in a perfect world. That's why we continue to seek better ways to build our software systems.

As realists, we acknowledge that no one process, technique, language, or platform is good for all situations. We increase the number of tools in our repertoire so that when we need that special tool or technique, we are well-prepared to use it.

The history of our industry is rife with examples of improvements in our approach to building software, from the introduction of high-level languages, structured programming, and the object-oriented approach, to the development of spiral and iterative methods, and so on. One of the latest entrants in this lineup is aspect-oriented programming (AOP)


What is AOP?

Ò Aspect-oriented programming (AOP) is a new programming technique that allows programmers to modularize crosscutting concerns.

Ò AOP introduces aspects, which encapsulate behaviors that affect multiple classes into reusable modules.

Ò With the recent release of AspectJ, Java developers can now take advantage of the modularization AOP can provide.


Foundation of AOP:

Aspect-oriented programming is one of those ideas that seems new but has actually been around for quite a while.

The person most commonly associated with AOP is Gregor Kiczales, currently at the University of British Columbia, where he works on software modularity research.

From 1984 to 1999, Kiczales worked on AOP at the Xerox (PARC) and was a leader in developing implementations of it.


How AOP Works?

  1. With AOP, we start by implementing our project using our OO language.
  2. Then we deal separately with crosscutting concerns in our code by implementing aspects.
  3. Finally, both the code and aspects are combined into a final code file using an aspect weaver.
  4. Then this final code goes through the compiler to generate the final executable.

Ò As a result, a single aspect can contribute to the implementation of a number of methods, modules, or objects, increasing both reusability and maintainability of the code.


Why AOP?

In an article entitled "Aspect-Oriented Programming," some of AspectJ's authors write about performance optimizations that drove a 768-line program into 35,213 lines. Rewritten with aspect-oriented techniques, the code shrank back to 1,039 lines while retaining most of the performance benefits.

AOP complements object-oriented programming by facilitating another type of modularity that pulls together the widespread implementation of a crosscutting concern into a single unit. These units are termed aspects, hence the name aspect-oriented programming.

Aspect-Oriented Programming (AOP) complements Object-Oriented Programming (OOP) by providing another way of thinking about program structure. In addition to classes, AOP gives you aspects. Aspects enable modularization of concerns such as transaction management that cut across multiple types and objects.


Cross-Cutting Concerns:

Ò The type of logging required in our example is a cross-cutting concern. It cannot be isolated or encapsulated in one or two specific classes; the logging involves changes in many places across the system. Our desire is to keep the system maintainable, and therefore we want our logging approach to keep the code as clean and simple as possible. We would also like to avoid significant structural changes to the system's architecture. So how do we implement a cross-cutting concern such as logging? We could refactor all of the code by creating a logging class and performing the appropriate insertions. However, in a large system, this would be a time-consuming, error-prone job.

Ò AOP is designed to handle cross-cutting concerns by providing a mechanism, the aspect, for expressing these concerns and automatically incorporating them into a system. AOP does not replace existing programming paradigms and languages; instead, it works with them to improve their expressiveness and utility. It enhances our ability to express the separation of concerns necessary for a well-designed, maintainable software system. Some concerns are appropriately expressed as encapsulated objects, or components. Others are best expressed as cross-cutting concerns.

Ò An example of crosscutting concerns is "logging," which is frequently used in distributed applications to aid debugging by tracing method calls. Suppose we do logging at both the beginning and the end of each function body. This will result in crosscutting all classes that have at least one function. Other typical crosscutting concerns include context-sensitive error handling, performance optimization, and design patterns.

Ò Crosscutting concerns may exist in some programs, especially large ones. However, in some situations, redesign of the system might transform a crosscutting into an object. AOP assumes that crosscutting concerns may exist in programs and can't be re-factored out of the design in all situations.


AOP by Example:

The best way to describe AOP is by example. Suppose you were responsible for maintaining a large software system that managed the payroll and personnel functions for your organization. What if management issued a new requirement that you create a log of all changes to an employee's data? This would include payroll changes, such as a change in the number of deductions, raises, overtime, and so on. It would also include any changes to the employee's title, personal data, and any other information associated with an employee. How would you go about meeting this requirement?

Most people, in the absence of a better way, would search through the code and insert calls to a logging method in appropriate places. If the system were well-designed and constructed, the code might require changes in only a few places. For most systems, though, insertions would be necessary in many places. If the system were object-oriented, we might build a logging class and then use an instance of it to handle the logging. We might need a hierarchy of classes to handle different files and databases. Attempting to fulfill the requirement in this way would not be a trivial job, and it would not be easy to ensure that we'd made all of the necessary insertions, either.

Even if we had a superior, object-oriented system implementation, we would encounter some problems. note that OO systems often produce classes that are difficult to change, and code that can't be reused and is difficult to trace through.


AOP Concepts:

Aspect: A modularization of a concern that cuts across multiple objects. Transaction management is a good example of a crosscutting concern in J2EE applications. In Spring AOP, aspects are implemented using regular classes (the schema-based approach) or regular classes annotated with the @Aspect annotation (@AspectJ style).

Join point: A point during the execution of a program, such as the execution of a method or the handling of an exception. In Spring AOP, a join point always represents a method execution. Join point information is available in advice bodies by declaring a parameter of type org.aspectj.lang.JoinPoint.

Advice: Action taken by an aspect at a particular join point. Different types of advice include "around," "before" and "after" advice. Advice types are discussed below. Many AOP frameworks, including Spring, model an advice as an interceptor, maintaining a chain of interceptors "around" the join point.

Pointcut: A predicate that matches join points. Advice is associated with a pointcut expression and runs at any join point matched by the pointcut (for example, the execution of a method with a certain name). The concept of join points as matched by pointcut expressions is central to AOP: Spring uses the AspectJ pointcut language by default.

Introduction: (Also known as an inter-type declaration). Declaring additional methods or fields on behalf of a type. Spring AOP allows you to introduce new interfaces (and a corresponding implementation) to any proxied object. For example, you could use an introduction to make a bean implement an IsModified interface, to simplify caching.

Target object: Object being advised by one or more aspects. Also referred to as the advised object. Since Spring AOP is implemented using runtime proxies, this object will always be a proxied object.

AOP proxy: An object created by the AOP framework in order to implement the aspect contracts (advise method executions and so on). In the Spring Framework, an AOP proxy will be a JDK dynamic proxy or a CGLIB proxy. Proxy creation is transparent to users of the schema-based and @AspectJ styles of aspect declaration introduced in Spring 2.0.

Weaving: Linking aspects with other application types or objects to create an advised object. This can be done at compile time (using the AspectJ compiler, for example), load time, or at runtime. Spring AOP, like other pure Java AOP frameworks, performs weaving at runtime.


Advantages of AOP Approach:

· AOP is designed to handle cross-cutting concerns by providing a mechanism, the aspect, for expressing these concerns and automatically incorporating them into a system. AOP does not replace existing programming paradigms and languages; instead, it works with them to improve their expressiveness and utility. It enhances our ability to express the separation of concerns necessary for a well-designed, maintainable software system. Some concerns are appropriately expressed as encapsulated objects, or components. Others are best expressed as cross-cutting concerns.

Ò Separate persistence and logging functionality.

Ò The logging concern is taken care of by the AOP interceptor.

Ò Decreases complexity.

Ò Promotes code reuse and modularization.

Ò The AOP interceptor is used by all methods in the DAOs.

Ò Makes it easier to change.

Ò Decouples the LogFactory from the DAO impl’s.

Ò The HibernateEventDAO is unaware of being logged.

Ò Makes re-use and testing simple.

Ò AOP lets you encapsulate functionality that affects.

Ò Multiple classes in a separate unit – an interceptor.

Ò Promotes separation of concern.

Ò Promotes code reuse and modularization.

Ò Promotes loosely coupled design.


Quality and Risks:

Ò Now that we've seen some benefits, let's look at some of the risks concerning AOSD as well as what is needed to bring it into the software development mainstream. The next sections discuss these issues.

Ò Having looked at AOSD from a quality viewpoint and done a little exploring with AspectJ, I've seen potential risks along with the benefits. I will discuss three issues that illustrate some of the challenges we may face with respect to quality as AOSD becomes more popular.


Issues:

· The first issue is how we will need to modify our process to accommodate AOP. One of the most effective techniques for detecting software defects is through code inspections and reviews. During a review, a team of programmers critiques code to determine if it meets its requirements. With object-oriented programs, we can review classes, or sets of related classes, and reason about them. We can look at the code and determine if it handles unexpected events properly, has logical flaws, and so on. In an OO system, each class completely encapsulates the data and behavior of a specific concept.

With AOP, however, we can no longer reason about a class just by looking at the code for it. We do not know whether the code might be either augmented by advice from some aspect or completely replaced by such advice. To be able to reason about an application's code, we must be able to look at the code from each class as well as the code for any aspects that might affect the class's behavior. However, it is possible that the aspects have not been written yet. If that is so, then how much can we truly understand about the behavior of the application class's code when we consider it in isolation?

In fact, the way to think about correctness in AOP code is the inverse of how we consider it for object-oriented programming (OOP) code. With OOP, we go from inside out: We consider a class, make assumptions about its context, and then reason about its correctness, both in isolation, and in terms of how it will interact with other classes. With AOP, we need to look from the outside in, and determine the effects of each aspect on every possible join point. Determining how to reason correctly about AOP, and developing the appropriate techniques and tools to help us, is a rich research area.

· A second, more practical issue regarding the potential widespread adoption of AOP is the development of tools and techniques for testing, especially unit testing. Because code may be changed by an aspect, unit tests that run perfectly on a class may behave quite differently when the class is integrated into an AOP system. The following example illustrates this point.

As you probably know, a stack is a data structure that is used to add and remove items in a last-in, first-out manner. If you push the numbers 2, 4, and 6 onto a stack and then pop the stack twice, you will get 6 and 4, in that order. Writing a unit test for a Stack class is straightforward. We can read the requirements specification and the code and do a very good job of ensuring that the implementation is correct. One of the first things I did when I began to look at AspectJ was to implement a stack and see what I could do with aspects to change the behavior. I implemented a simple change: Increment each item by 1. This is very easy to do. Now, my unit test -- which pushes 2, 4, and 6 onto the stack and pops the top two elements off to verify that they are 6 and 4 -- fails. The code that the unit test is testing did not change, yet the behavior changed. Instead of 6 and 4, the results are now 7 and 5.

This is a trivial example, and one that probably would not occur in a real-life situation. But it shows that a malicious programmer can cause a lot of harm quite easily. Even if we ignore malicious programmers, many defects occur because there are unwanted side effects of changes we make. It might be very difficult to ensure that an aspect implemented for very valid reasons does not have unwanted effects on existing program functionality.

· The third issue is the testing process itself. Once we have a set of tools and techniques, how do we modify our testing process to use these effectively and support our overall development goals? Although this issue may not be a major one, I believe it will need to be addressed before we can really do a good job of testing software built with aspects.


Other Barriers to AOSD Adoption:

Ò Quality issues may be the biggest deterrents to adopting AOSD methods, but they are not the only ones.AOSD is a new paradigm. As did other paradigms when they were new (e.g., object-oriented software development), this one will take time to be adopted widely because it involves a learning curve. First we must learn basic techniques and mechanics, then advanced techniques, and then how to best apply the techniques and when they are most appropriate.

Ò Tools will play a major part in industry adoption of AOP. In addition to compilers and editors, we need tools to help us reason about systems, identify potential cross-cutting concerns, and help us test in the presence of aspects. As we find methods to help us represent the systems better, such as representing aspects in UML, our tools must evolve to support these methods.


Conclusion:

Ò Aspect-oriented technology has many potential benefits. It provides a way of specifying and encapsulating cross-cutting concerns in a system. This might, in turn, allow us to do a better job of maintaining systems as they evolve — and we do know that they will evolve. AOP would let us add new features, in the form of concerns, to existing systems in an organized manner. The improvements in expressiveness and structure might allow us to keep systems running longer, and to incrementally improve them without incurring the expense of a complete rewrite.

Ò AOP may also be a great addition to quality professionals' toolboxes. Using an AOP language, we might be able to test application code automatically without disturbing the code. This would eliminate a possible source of error.

Ò We are in the early stages of understanding the full potential of AOSD. It seems clear that the technology offers enough benefits to warrant further exploration and experimentation. How far are we from everyday usage of AOP languages for application development? It depends on whom you ask.

Ò Clearly, we have a way to go in developing tools and processes to make AOP viable for everyday use. However, I do not believe that any of the issues I have discussed in this article represent insurmountable problems. I do believe that when we have developed a proven set of tools and processes for AOP, we will have a better way to build software than we do today.

Ò As Barry Boehm said about agile processes, 2 we must approach AOP with care. Whether we are early adopters or we wait for this technology to become more mainstream, we need to ensure that our software investment will provide acceptable returns today and in the future. That's just good business sense.


Is AOP worth using?

Grady Booch describes aspect-oriented programming as one of three movements that collectively mark the beginning of a fundamental shift in the way software is designed and written. AOP addresses a problem space that object-oriented and other procedural languages have never been able to deal with. Within a few weeks of my introduction to AspectJ, I've seen it provide elegant, reusable solutions to problems I thought were fundamental limitations of programming. It's fair to say that AOP is the most powerful abstraction I've learned of since I began using objects.


MOVING TOWARDS A BETTER WAY TO BUILD SOFTWARE