Aspect-Oriented Software Development

Eric Kenseth Department of Software Engineering University of Wisconsin – Platteville [email protected]

Abstract

Aspect-oriented software development is a new type of software development that increases modularity and cohesion of code. However these desirable results require a new approach to the software engineering lifecycle. From requirements gathering all the way through maintenance, the way of approaching problems is changed when using aspects. Some issues exist within these stages as well, mostly due to the youthful nature of the approach. Overall, the goal of keeping code cohesive and separate from other concerns brings about increased maintainability and modularity that may make these problems worthwhile to overcome. Aspect oriented software development is certainly a new and interesting model that can be useful on certain projects.

Introduction

As the problems software need to solve have become larger and more complex, new methods of solving these problems have been created. While object-oriented methods have allowed for systems to be designed in a better way, there are some problems objects cannot handle in an entirely ideal way. These problems spurred research efforts in the nineties to create a way to solve the shortcomings of objects. Aspect-oriented software development is the result of efforts put forth at the Xerox Palo Alto Research Center.

Terminology

Aspect-Oriented Software Development uses several terms that need to be defined in order for proper comprehension of the discipline be achieved. First and foremost of these terms is called a concern. A concern is any demand or expectation placed on a software system by any stakeholder of that system. It is important to realize that demands and expectation may include secondary details of the system such as time efficiency, system security, and portability. In addition to this, all stakeholders must be considered; including ones that may normally be overlooked such as the developers, all the types of end-user, and the system itself.

A subtype of concerns that is very important when dealing with aspect-oriented techniques is cross-cutting concerns. Cross-cutting concerns are concerns that are far reaching and deal with several different areas of the software system. Cross-cutting concerns are the major motivation for aspect-oriented software development as well as several other models that attempt to solve them. This is because object-oriented techniques do not particularly address the issue and solutions to these concerns in object- oriented have assorted downsides.

Separation of concerns is the primary desired goal of aspect-oriented software development. Separation of concerns is accomplished when all small pieces of the software system can be traced back to only one set of strongly related concerns and all concerns can be traced to only one set of strongly related pieces of the software system. A system that cannot do this has not achieved proper separation of concerns and will show signs of scattered concerns and tangled code. Tangled code is segments of code that exist in order to accomplish one concern but has within it code that deals with other concerns. A scattered concern or the scattering of code refers to a concern that has code implementing it in many locations throughout the system instead of a single cohesive point. [9]

Much of the work when dealing with aspect-oriented techniques revolves around the existence of joinpoints. Joinpoints are locations within the code that are highly visible by the system. Primary examples of joinpoints are method calls, method returns, and exception throws. Field access may also be considered a joinpoint in some contexts. Joinpoints are entirely language dependent, so the language being used determines what joinpoints are available.

A pointcut is a specially defined subset of joinpoints. The exact method of defining which joinpoints are within a pointcut is language dependent. The reason behind defining a pointcut is to deal with implementing a cross-cutting concern. This is capped off with advice, which is code used to service a cross-cutting concern by running whenever a joinpoint within its pointcut is reached. Advice runs in the context of the current joinpoint, which allows the code in the advice access to variables and other data within the context. Also, advice has the ability to change program flow in a number of ways. [9]

An aspect is the namesake of aspect-oriented techniques and serves the purpose of a class in that it encapsulates a cross-cutting concern. It shares many similarities with classes but also has a few key differences. Like classes, aspects may be static or dynamic, abstract or not, and non-abstract aspects may be instantiated. Inheritance can occur with aspects. Aspects can have fields and methods just the same as normal classes. The primary difference with aspects is that they may contain pointcuts and advice in order to service its cross-cutting concern. Furthermore, aspects can be designated to be privileged, allowing them access to normally private methods and fields in a given class. While that final allowance violates the common rules of encapsulation, aspect-oriented philosophies suggest that the gains allowed are more beneficial than the losses incurred because of it. [9] Changes to the Software Lifecycle

Early Phases

In the requirements and analysis phase of the software engineering life-cycle, aspects do not require any further information than is typically needed at this time, but do manage to look at information from a somewhat different angle than other techniques. While it is important in all methodologies of software engineering to recognize the concerns of the system, whether or not they are called concerns, aspect-oriented software development goes further in classifying each of these concerns. Concerns for the system are broken down into two types: core concerns and cross-cutting concerns. Core concerns are the concerns that will make up the primary structure of the system, while cross-cutting concerns are the other concerns and constraints that are placed on the system throughout.

There are many types of common cross-cutting concerns. The most common cross- cutting concern mentioned with regards to aspects is that of logging, as proper logging of the system requires intervention of the logger throughout the system. Security concerns also exist in many places, if the system requires it. Error detection and correction can be a cross-cutting concern depending on the methods the system is going to use in their regard. If a system is large enough to worry about memory management, it is going to do so in many locations. Also, many real-time and synchronization concerns, including mutual exclusion, are cross-cutting concerns. Sufficiently complex rules for the system may also be considered, depending on how much of the system must be monitored to ensure compliance. [3]

Aspects can be treated differently when use cases are concerned. Use cases made for a cross-cutting concern will be much more generalized in terms of context, but very detailed in terms of steps. This leads to them not being very useful for customers, but much more useful for designers who benefit from being able to see every step in full detail that the aspect solving the concern is going to need to do. The aspect use cases will also make the rest of the use cases for the system easier to create, as most of those other use cases will end up including or being extended by the aspect use cases. [3]

Design

As software enters into the design phase, a relatively major problem of aspect-oriented software development is encountered. The problem is the complete lack of standardization in designing with aspects. UML does not formally support aspects, so a team using aspect-oriented software development is going to need to decide upon their way of approaching design with aspects. One approach on how to represent aspects on a class diagram can be seen in figure 1, where an aspect is crosscutting into an abstract shape class in order to encapsulate the common concern of updating the display anytime a shape changes. [1] Figure 1: Section of an aspect-oriented class diagram.

Despite the inconsistencies on how to approach design diagrams, sequence diagrams are very useful and important when using aspects. By showing the flow of the system through method calls as well as into the aspects joined to said method calls, the use of the aspects involved is very visibly demonstrated. This can help increase comprehension of the system and also help to indicate how pointcuts are going to be needed to be set. [1]

Design Patterns

There are certain concerns that arise often during the design of software systems. These are concerns or types of concerns that have appeared in many systems. Due to this, design patterns have been created as a standardized way of solving these problems. While many normal object-oriented design patterns work quite well, aspect-oriented techniques allow for aspect patterns to come into existence to solve various problems. Often these aspect patterns are in assorted ways more beneficial to the system then the object- oriented patterns that could be used to solve the same problems.

The most common and simple example of an aspect-oriented design pattern is the spectator pattern. The spectator pattern exists to be used when a cross-cutting concern relies on observation of a large amount of the system. Most commonly, logging or tracing concerns can involve running simple code at the beginning and end of every method call. The pattern used to solve this is simple with aspects. Creating an aspect with the simple advice that needs running tied to a large pointcut set that covers the necessary sections of the system allows for a simple solution to the concern. [4]

While the spectator pattern does not do anything that object-oriented techniques could take care of, there are several advantages in the aspect solution. A solution not using aspects and this pattern would have required calls at the beginning of nearly every method in the system to the logger, tracing system, or whatever was taking care of the concern. Such a solution would lower cohesion of each module that had these tangled calls within them, as well as greatly increasing coupling of the cross-cutting concern with the rest of the system. With the aspect-oriented solution, the base code is completely oblivious to the cross-cutting concern, and as such if the interface changes or if the concern is entirely removed, those modifications are entirely centralized to one module. [5]

Another major pattern using aspects is the regulator pattern. This pattern solves the common need for designers to enforce assorted rules, such as ensuring proper security credentials or message filtering. The actual methodology of implementing a regulator pattern is very similar to that of a spectator pattern, as they both involve using a pointcut and advice to run similar code to take care of the concern in a single location. The primary difference is that regulator patterns may create a change in the system by changing fields, invoking methods, or otherwise changing program flow.[4]

As with the spectator pattern, the key benefits are that cohesion is increased and coupling decreased within the system. The key difference is that the system does need to be aware, on some level, that the aspect may change program flow, although with proper design this can become a non-issue. Primary uses of the regulator pattern are those of security, authorization checking, and message filtering, although there could be many more uses for the pattern. [4]

The patch pattern works to solve a problem that has emerged as the reliance on re-use has increased. Often times, libraries or other modules being reused lack a method that would be useful for the system they are now being used in. Modifying these libraries or modules may not be an option, and such modifications have downsides as well if it is possible to do so. Using a standalone privileged aspect with an inter-type declaration instead allows for such a method to be added to a class without modifying the library. Although this is a bit of a hack solution, it gets the desired effect. [8]

The primary benefit of the patch pattern is that it allows full addition or modification of a library or other reused module without any actual modification of the reused entity. This means that the needed methods can be called in a natural way by the rest of the system without going through auxiliary classes. Furthermore, since the base library or module has remained unchanged, it can be updated with minimal effort if a new version were to become available. [8]

There are some downsides with the patch pattern. First of all, these patched-in methods may change fields in ways unexpected by the base code, which could cause unforeseen problems. Secondly, multiple patches on the same piece of base code must be careful not to interfere with each other. Finally, there is an issue of the aspects being cohesive with the base code but not being in the base code; however, that is the issue that caused the patch in the first place. [4]

Implementation Concerns

There are a handful of concerns faced when using aspect-oriented development. The primary concern is language selection. As aspects are a new language feature, the language used in implementation must have been created to allow the use of aspects and the compiler or interpreter must support aspects. The good thing is that there have been numerous languages created to support aspect-oriented programming. Most of these languages are closely based on common languages and only have a few additions or changes to them. The best known language for aspect-oriented programming is AspectJ, which was developed at the birth of aspect-oriented programming as an extension to Java. The modifications to the language are completely additive in nature, so any valid Java program should work in AspectJ without modification. [7]

Almost all major languages have had aspect-oriented spinoffs of themselves created. C and C++ have a number of variations, and there is an existing spinoff of all .net languages. Even assorted minor languages have had spinoffs of them created to work with aspects. This availability of language selection and the backwards-compatible nature of most of the languages can be helpful if old code is going to be reused in a new aspect- oriented system.

Testing and Maintenance

The testing phase for a system using aspect-oriented software development has a few gains and a few losses when compared to other forms of development. There are great gains made in testing and debugging caused by the availability of development aspects. Development aspects are aspects that can be inserted into the system for development but possibly removed later before the system is deployed. Common development aspects are aspects that perform tracing, logging, profiling, or performance and memory monitoring tasks. These are all tasks that can provide a lot of useful information to developers, but they are often difficult to include in a system under normal circumstances due to the high coupling such concerns have if implemented without aspects. With aspects, however, they are completely encapsulated into a single aspect and are quite simple to add and remove from the system. One of the other great benefits is that once these aspects have been created in a way fitting a development team, the same developmental aspects can be used on any project of that language. [6]

There are problems when it comes to testing aspects. Because aspects lack an independent identity and are instead coupled with the context of the joinpoint that they intrude upon, they cannot be tested using many of the common testing methods, such as unit tests. Also, aspects introduce new ways for a system to have faults. Incorrect pointcut definitions can cause advice to run when it shouldn't or not run when it should. Incorrect ordering of aspects can cause unintended behavior when multiple pieces of advice activate on the same joinpoint in the incorrect order. These new faults need to be watched for, but the problem is that there is no real way to look for them. Aspect-oriented techniques are still young, and no systematic way of testing aspects has yet been proposed. This does not mean they cannot be tested, as proper system-wide testing should still find any faults that exist; however, it is rather undesirable to leave any faults in the system for that long. New ways of testing aspects are needed. [6]

During the maintenance cycle, aspect-oriented software development has many advantages that can be used many ways. Bug-fixes and modifications are made far easier due to the separation of concerns created using aspects. Locating the concern a bug is in is normally a relatively simple task, and since aspect-oriented development has separated concerns from each other, the total code within that concern is smaller, either by not being spread out or by not being tangled with other code. This makes finding the malfunction easier. [3] Furthermore, modification of any scale to any part of the system is easier. Entire concerns can be removed or added with a lot fewer worries. Any desires to not change the base code can be fulfilled by using aspects for all modifications at this point, although it may not be the most efficient way of solving things. It would, however, allow for functionality to switch between patched and pre-patched versions of the code if such ability were needed. It is worth noting that there are some new worries introduced due to aspects in the maintenance phase, such as the need to verify the correctness of pointcuts should the set of all joinpoints be changed. New function calls creating new joinpoints may cause old pointcuts that cut into related methods to not act as desired, so such things should be tested. [2]

Reuse

A major desire in software engineering is to increase code reuse in new systems as it saves development time. Aspects are a great boon to this desire as some of their main effects is increased modularity of the system and separation of concerns. As such, code modules are much easier to reuse, not needing to prune out tangled concerns or worry about re-scattering code throughout a new system. Many common aspects are useful in almost all systems as well. Logging, tracing, and profiling aspects can be valuable in all systems, whether they are only kept for development, or if they are later deployed to help add valuable detail to user bug reports. [2]

Benefits and Losses of Aspect-Oriented Software Development

There are a number of benefits gained by using aspect-oriented techniques in comparison to object-oriented techniques. The primary benefit from the transition is increased modularity. As concerns have been separated, the system's modules that were implemented to solve a given concern are not tangled with calls to modules that deal with unrelated, cross-cutting concerns. Furthermore, those cross-cutting concerns are not scattered about and are instead packaged into a single module. This, in turn, has several benefits throughout the software life-cycle that were described above, such as increased maintainability and reusability.

An additional benefit of aspects is that of a reduction in the size of code. As aspects collect commonly-repeated code into advice with a pointcut to where that code is relevant, the code-base will be smaller with aspects than without. [5]

The major losses of aspect-oriented development are those of efficiency and security. Security risks of aspects and how to mitigate these risks have not been well studied, making aspects unsuitable for a system that needs to ensure the highest security standards. Efficiency is also somewhat reduced due to the increased overhead aspects have; however, this problem is far from dire in most situations. [5]

Another major loss of aspect-oriented development is the lack of a formalized way to approach certain things. The lack of UML support and lack of systematic ways of testing aspects are problems that need to be solved before aspect-oriented development can become more widely used.

Also, the benefits must be qualified by the fact that they are only fixes to problems in other developmental approaches. If a system was small enough or did not contain any cross-cutting concerns, those problems would never have come about and the system will not benefit much from an aspect-oriented approach. Inversely, the benefits will be even greater if a system would have needed to address several cross-cutting concerns within it. This means that aspects are perhaps not the proper solution to every problem, but can still be a powerful tool in the right situation.

Conclusion

Aspect-oriented software development is a new approach to software development that attempts to fix the cohesion and coupling problems faced when dealing with cross-cutting concerns. The philosophy of creating separation of concerns by use of aspects does allow for the desired effects and certainly creates increased modularity. This approach requires changes to how the software lifecycle is approached in many locations; however, these changes still lack some refinement. The youth of aspect-oriented development can be seen in its lack of a formalized design language and its lack of a systematic way of testing aspects. These problems need to be solved before aspect-oriented development can become widespread, but it needs to be used and researched more before that can happen. Still, as it is, aspect-oriented software development seems to have a lot of benefits within it and should not be overlooked.

References

[1] O. Aldawud, T. Elrad, and A. Bader. (2003) UML profile for aspect-oriented software development. In Proceedings of the AOM workshop at AOSD, 2003

[2] Hachani, O., Bardou, D. (2002) Using Aspect-Oriented Programming for Design Patterns Implementation. In: OOIS 2002 Workshop on Reuse in Object-Oriented Information Systems Design

[3] Blair, G., Blair, L., Rashid, A., Moreira, A., Araujo, J., Chitchyan, R. (2005). Engineering Aspect-Oriented Systems. In Fillman, Elrad, Clark, Aksit (Eds.), Aspect- Oriented Software Development (pp.380-398). [4] James Noble, Arno Schmidmier, David J Pearce, Andrew P Black (2007) Patterns of Aspect-Oriented Design. In Proceedings of European Conference on Pattern Languages of Programs. Irsee

[5] Filman, R. & Friedman, D. (2005). Aspect-Oriented Programming Is Quantification and Obliviousness. In Fillman, Elrad, Clark, Aksit (Eds.), Aspect-Oriented Software Development (pp.1-7). Boston: Addison-Wesley.

[6] R. T. Alexander, J. M. Bieman, and A. A. Andrews. (2004) Towards the systematic testing of aspect-oriented programs. Technical Report CS-4-105, Department of Computer Science, Colorado State University, Fort Collins, Colorado.

[7] AspectJ. (n.d.). Retrieved January 30, 2010 from Eclipse website, www.eclipse.org/aspectJ

[8] A. Colyer and A. Clement. (2004) Large-scale aosd for middleware. In AOSD, 2004.

[9] Aspect Oriented Programming / Aspect Oriented Software Design. (2003). Retrieved January 30, 2010, http://www.codeproject.com/kb/architecture/aopByMarcClifton.aspx