Aspect Oriented Programming is used in the OBS Framework to automate the tailoring process of the components provided by a software framework. The present page gives a brief introduction to AOP. Readers who would like to have a more exhaustive discussion of AOP in the context of generative programming can turn to the book Generative Programming: Methods, Tools and Applications by : Czarnecki and Eisenecker (Addison-Wesley, 2000).
It should be stressed that AOP is a comparatively new and fast evolving field. Hence many of the considerations presented below may become rapidly obsolete. This applies in particular to the discussion oflanguage support for AOP.
Aspects
The same software application can be looked at from different perspectives and each perspective defines a model to represent the application. The termaspect designates one particular perspective and its associated model.
As an example, consider a real-time application. There are at least two obvious perspectives from which such an application can be considered: the functional perspective and the real-time perspective. The former perspective privileges the description of the algorithms and logic that are implemented by the application. A suitable model for it could be a UML class diagram that shows how the modules making up the application are organized and describing the functional behaviour that each of them implements. The real-time perspective of the application instead privileges its timing-related properties (execution times, timing distribution of its inputs, output deadlines, etc). A model describing this perspective might cover issues such as: the tasks making up the application, their scheduling policies, the synchronization mechanisms that are used to protect shared resources, etc. Each of these two perspectives defines an aspect and a model of the application.
An example of a less obvious type of aspect might be the algorithm optimization policy used in the application. If the application includes computationally intensive segments, it may make sense to define a general "optimization model" that might cover issues like: implementation of matrix operations, handling of sparse data structures, implementation of floating point operations, etc.
The error handling approach provides still another example of an aspect. If recording of run-time errors is important for an application, a model could be defined that describes which types of errors should be checked for and the actions that should be taken when errors are detected.
It should be stressed that there is no fixed set of aspects that is important for all applications. The aspects outlined above are just examples of potential aspects but, clearly, different applications have different concerns and therefore different sets of applicable aspects. The important point to note that, in order to capture the entire behaviour of an application, it will normally be necessary to consider several aspects. Traditional modelling and programming approaches have privileged the functional aspect but, except for trivial cases, this needs to be complemented with other aspects.
Motivation
The AOP paradigm was introduced to help handle multiple aspects of an application. More specifically, AOP allows the principle ofseparation of concerns to be applied to all aspects of an application.
The principle of separation of concerns states that a model of an application should be organized as a set of lower level units where each unit encapsulates one particular feature of the application. The advantage of this approach is that the description of a feature is localized and is therefore more easily controllable. The problem addressed by AOP arises from the fact that application of the principle of separation of concerns to different aspects of the same application typically gives rise to organizations of the associated models that are difficult to map to each other. This is illustrated in the figure. The figure shows two models (aspects) of the same application. Each model addresses a particular aspect of the application and each model is organized according to the principle of separation of concerns. This means that each model represents the application as a set of lower-level units (the small darker boxes). Since the two models are intended to represent the same application, there must exist some kind of mapping between them. Ideally, one would like this mapping to hold both at the level of the models themselves and at the level of the modular units into which the models are decomponed (i.e. one would like features that are encapsulated in a single modular unit in one model to be mapped to features that are encapsulated in a single modular unit in the other model). Unfortunately, this is usually not possible. The more normal situation is the one shown in the figure where a modular unit of model A is mapped to several modular units of model B. This is schematically shown in the right-hand side of the figure where the two models are "superimposed" and where a feature of the green aspect is shown to affect several modular units of the yellow aspect. Using the terminology of AOP, this fact is often expressed by saying that the green aspect cross-cuts the yellow aspect.
Modelling techniques have also been developed for some other typical aspects but, traditionally, it has been impossible to enforce the principle of separation of concerns with respect to more than one aspect at the same time. To illustrate, and with reference to the examples given in the previous section, consider the case of an application where both functional and error handling aspects are important and assume that the application is implemented in a class-based language such as Java or C++. In that case, the principle of separation of concerns can be applied to its functional aspect by suitably designing the classes and their interactions. It will then often be possible to localize the code that implements a particular functional requirement in a specific class (or even in a specific method of a class). This has several advantages:
- Checking the correctness of the implementation of the requirement is easy because only one class/method needs to be checked
- Changing the implementation of the requirement is easy because the change only affects one single class/method
- Responding to a requirement change is likely to be easy because the change can often be accomodated with changes in a single class/method
- Never check the return values of methods (i.e. ignore all errors)
- Always check the return value of all methods and, if an error is reported, create an entry in a log file
- Always check the return value of all methods and, if an error is reported, perform a software reset of the application
The AOP paradigm provides efficient ways to express aspects and to implement specifications of aspects into application code in a manner that preserves the principle of separation of concerns. The process of modifying an existing code base to modify the implementation of a certain aspect is called theaspect weaving process. Several different AOP languages exist that implement aspect weaving in different ways. The next two sections describe two typical approaches.
AOP as Code Generation
At its most basic, aspect weaving can be seen as a source code transformation process and the aspect oriented language can be seen as a sort of meta-language that specifies the code transformation. AOP then becomes a form of automatic code generation where both the starting and the end code are written in the same language. This view of AOP is illustrated in the figure.
To illustrate, consider again the previous example of implementing different error handling policies in a certain piece of code. The code on the left-hand side of the next figure represents the base code which does not implement any error handling. The error handling policy is encoded in an aspect program (not shown in the figure). After the aspect weaving process, a new modified program is automatically generated that is identical to the base program but which includes new code that implements a particular error handling policy. In the case of the figure, the error handling policy consists in checking the return code of all methods and, if this indicates an error, in commanding an application reset. The new code inserted by the aspect weaver is shown shaded in the right-hand box in the figure.
AOP as Compiler Extension
The previous section proposed a view of aspect oriented programs as source code transformation. A second view of an aspect oriented program is as an extension of the compiler of the base language. This is illustrated in the next figure.
As an example of the use of this technique, consider a base program that is written in
C/C++ and that is designed for use in a purely sequential environment (i.e. no
concurrency). Assume then that it is desired to adapt this program to be used in a
concurrent environment. This will, among other things, require that some sections of the
original code be protected against unsynchronized access by concurrent threads of
execution. Introduction of synchronization code is a classical example of implementation
of an aspect in that it requires the same type of change to be made in many different
parts of the code. One way to simplify this task is to extend the C/C++ compiler with a
new keywordsynchronized
with the same semantic as the
synchronized
class qualifier in Java. This would allow selected classes in
the base code to be endowed with access synchronization mechanisms. The definition of
the synchronization mechanism would be done only once and in only one location (the
meta-level program) and would then be projected onto the base code by the extended
compiler as part of the compilation process.
Language Support
The AOP paradigm is comparatively new and language support is still limited but growing fast. A good overview of the AOP scene can be found at:http://aosd.net/.
Among AOP languages, the most mature is AspectJ which is targeted at Java. The AspectJ compiler and related documentation is available as public domain software from this web site:http://www.eclipse.org/aspectj/.
The success of AspectJ has spawned several attempts to port its AOP model to other target languages. Most notable among them are AspectC++,AspectC andAspectC# which, as their names imply, target C++, C and C#, respectively. All three languages are developed by academic institutions and are or will be available for free. AspectC++ is the most mature of the three but is only available as a beta version. A company,pure-systems, has recently been set up to market a plug-in for Visual Studio that implements AspectC++.
In the C++ world, arguably the most mature and effective way to do AOP is provided by OpenC++. OpenC++ was first introduced in 1995 as a source-to-source translator facilitating development of C++ language extensions, domain specific compiler optimizations and runtime metaobject protocols. It is thus not strictly speaking an AOP language but it can support aspect-oriented programming. OpenC++ is available as free open source software.
Finally, in the Automatic Control Laboratory and at at P&P Software (a research spin-off of ETH), work is under way to develop theXWeaver as a non-intrusive weaver for C++ code. XWeaver is non-intrusive in the sense that it minimizes the impact of the weaving process on the base code and it can produce modified code that is as readable and can comply with the same coding and documentation rules as the base code. XWeaver is therefore especially suited to the generation of code that must undergo a certification process.