Aspect-Oriented Software Development
Separation of concerns (high cohesion) is one of the goals of modern software systems, for
reasons including reusability and maintainability. Traditional means of decomposition can
achieve high cohesion in simple systems. However, if requirements for interests such as logging
and security are added to a system, the amount of cohesion decreases – as does the reusability
and maintainability of the system’s modules. Aspect-Oriented Software Development (AOSD)
offers new techniques of decomposing a system by isolating the implementations of these
additional requirements into their own modules. These techniques can be used not only on code
via Aspect-Oriented Programming (AOP), but in every part of the software lifecycle. By using
AOSD, a complete separation of concerns – functional cohesion – can be achieved.
Before discussing aspect-oriented software development, it’s important to first discuss some
concepts that are responsible for its existence. Without this basis, understanding the need for
(and purpose of) AOSD can be very difficult.
Every software system has stakeholders, and those stakeholders give requirements specifying
what they would like the system to do/what properties they would like the system to have (ease-
of-use, performance requirements, etc.). The requirements given by a stakeholder reflect the
concerns that stakeholder has for the system. For example, supposed a stakeholder gives the
requirement, “The system shall require user authentication before allowing a user to transfer
funds.” The concern the stakeholder seeks to address is security.
Separation of Concerns
Key principles in software engineering are decomposition, abstraction, encapsulation,
information hiding, and separation of concerns. These principles support the idea of
modularity, an essential property of any software system. In particular, separation of concerns
means ensuring “that each module only deals with one concern.” This results in functional
cohesion, since each module is performing one – and only one – task.
Functionally-cohesive systems have many benefits over systems with lower cohesion. One such
advantage is in the system’s maintenance. When changes are required, the “desired changes can
be easily localized and will not propagate.” Other benefits are that the system has greater
understandability, extensibility, reusability, and adaptability. Essentially, making changes to
a functionally-cohesive system is cheaper than making the same changes to a less-cohesive
One issue that prevents a system from becoming functionally-cohesive is tangled concerns. This
occurs when “multiple concerns are interleaved in a single module.”
Figure 1: An example of the tangled logging and security concerns
Consider the code in Figure 1. The calls to methods in Logger are implementations of a logging
concern, and the call to Security’s VerifyAuthentication method is an implementation of a
security concern. However, the main concern of the TransferTo method is account management.
Thus the logging and security concerns are interleaved, or tangled, in the TransferTo method.
According to , “the complexity due to such tangling… [becomes] a major obstacle to ease of
code development and maintenance.”
Scattered concerns are another problem that results in a less-cohesive system. A concern is
“scattered” when it affects multiple modules. For example, a reporting concern’s
implementation may require a PrepareActivityReport method in a User module, a
PrepareFundChangesReport method in an Account module, and a PrepareFailedLoginsReport
method in a Security module. The reporting concern is “scattered” because its implementation is
scattered among multiple modules.
Even in a well-designed system, there will inevitably be concerns that become tangled and
scattered among other concerns. The scattered and tangled ones are called cross-cutting
concerns, because they inherently “cut across” other modules in the system. If a system has
requirements for concerns such as synchronization, memory management, security, caching,
logging, or monitoring  (to name a few), then those concerns will be cross-cutting and will
result in scattering and tangling.
Why are cross-cutting concerns such a bad thing? Because the implementation of a cross-cutting
concern is spread among and tangled in the code of various modules, it can be difficult to
understand. Additionally, the reusability of a module can be hindered by cross-cutting
concerns. In order for a module to be reusable, it must first be examined to find any code from
cross-cutting concerns. That cross-cutting code must then be removed, resulting in an entirely
reusable module consisting only of code with a single purpose. The system can also be
difficult to maintain, since making a change to a cross-cutting concern’s implementation requires
that the maintainer locate all affected locations in the code. Some affected locations may be
missed, introducing bugs into the system. The likelihood of this happening increases for each
location that must be checked, so minimizing the number of modules a concern cuts across is
very important for a well-functioning system.
Before describing what aspects are, it should be noted that there are some inconsistencies
regarding the definition of an aspect. The definition of an aspect from an implementation
viewpoint is quite different than its definition from a conceptual viewpoint. In addition, to
understand exactly what an aspect is in either case, there are a number of terms that must first be
described. The following are two definitions of aspects – the first from the conceptual
viewpoint, and the second from the implementation viewpoint.
Aspects, according to , are “design decisions…[which are] difficult to cleanly capture in
actual code…[because] they cross-cut the system’s basic functionality.” In this definition, an
aspect is being equated with a cross-cutting concern. Later,  elaborates on this by stating “a
property that must be implemented is…an aspect, if it can not be cleanly encapsulated in a
generalized procedure.” Thus, a concern is an aspect if it cannot be encapsulated in a traditional
However, aspects are defined in  as “a program abstraction that defines a cross-cutting
concern”. This definition equates an aspect with the implementation of a cross-cutting concern
(it should be noted here that the definition in  was made 14 years after the definition in , so
a change of definition may have occurred in that time). Thus, the concern is viewed as a distinct
module with pieces that cross-cut other modules. This definition is examined further in the
Aspect-Oriented Programming section below.
Closely related to concept of aspects is what qualifies a language or process as “aspect-oriented”.
According to , for something (a language, for example) to be aspect-oriented, it must possess
“quantification and obliviousness”. It possesses quantification if it allows aspects to affect
multiple places in a system (a.k.a. cross-cutting), and it possesses obliviousness if it ensures that
other modules are unaware of the aspect affecting them (this enforces separation of concerns).
Anything with aspect-oriented in its name ideally follows these two criteria.
Aspect-Oriented Software Development
Aspect-oriented software development (AOSD) is an approach to software development that
“provides better separation of concerns by explicitly considering cross-cutting concerns.” As
a software development approach and not simply a programming methodology, AOSD consists
of adaptations to each part of the software lifecycle. Initially, however, only the implementation
phase had an aspect-oriented approach. This approach is known as aspect-oriented
In June of 1997, Gregor Kiczales and his team from the Xerox Palo Alto Research Center
presented a paper at the European Conference on Object-Oriented Programming (ECOOP). The
title of their paper was “Aspect Oriented Programming”. This paper formally captured what an
aspect is and why writing clean code with cross-cutting concerns is so difficult. In their paper,
experimental programming languages were devised and examined which attempted to isolate
aspect code in a single module. This would enable clean code to be written and would
achieve high levels of cohesion.
The research done by Kiczales and his team proved worthwhile. Since the introduction of
aspect-oriented programming (AOP), aspect-oriented approaches to each phase in the software
lifecycle have been developed and the International Conference on Aspect-Oriented Software
Development has been created. In addition, there are now aspect-oriented extensions to over
twenty commonly-used programming languages, including C++, COBOL, Java, Ruby, and
AspectJ is a highly popular aspect-oriented extension to the Java programming language. It was
also developed by Kiczales and his team and was a result of the experimental aspect-oriented
languages found in . Because of its widespread acceptance and use, it has been chosen as the
language for the examples in this paper.
Aspects in AOP
Now that aspect-oriented programming and the AspectJ language extension have been
introduced, the second definition of what an “aspect” is can be revisited. As defined in , an
aspect is “a program abstraction that defines a cross-cutting concern.” The definition continues,
saying “It includes the definition of a point-cut and the advice associated with that concern.”
There are a couple new terms in the second part of that definition: point-cut and advice. These
terms, and other AOP-related terms, are described in detail below.
The advice in an aspect is the code that would normally be found tangled in other modules in the
system. As stated by , advice is “the code implementing a concern.” For example, consider
the tangled code in Figure 1. The call to Security’s VerifyAuthentication method is advice that
would be placed in an aspect for the Security module, and the calls to Logger’s BeginLog, Log,
and EndLog methods are advice that would be placed in an aspect for the Logger module.
An interesting ability of many aspect-oriented programming extensions is that they allow what
are called “inter-type declarations” to be made in the aspect. According to , an inter-type
declaration allow a developer to “modify the static structure of a class” ( uses “introduction”
instead of “inter-type declaration”, but “inter-type declaration” is a newer and more self-
descriptive term for the concept). A user can make the following inter-type declarations in
AspectJ: “Add fields and methods[,] Change the parent of a class[, and] Add interfaces to a
class.” An example of two inter-type declarations is shown in Figure 2 below.
Figure 2: Two inter-type declarations for ReportingAspect
In Figure 2, two inter-type declarations were made. In the first, the method
PrepareActivityReport is added to the User class. In the second, the PrepareFundChangesReport
is added to the Account class. By removing these methods from User and Account and putting
the methods into ReportingAspect, the reporting concern has been separated from the core
system and all three affected modules now have greater cohesion.
Join-Point and Join-Point Model
A join-point is “an event in an executing program where the advice associated with an aspect
may be executed.” A join-point model is “the set of events that may be references in a
pointcut.” Since pointcut hasn’t yet been defined, another description is that a join-point
model is the set of events that are supported by a particular aspect-oriented language. In
AspectJ, the join-point model consists of call events, execution events, initialization events, data
events, and exception events. Call and execution events pertain to when a method or constructor
is called or executed, initialization events are when a class or object is initialized, data events are
when a field is accessed or updated, and exception events are when an exception is handled.
Only these join points are in AspectJ’s join-point model, so events such as a call to super()
cannot be used as a join-point in AspectJ.
A point-cut is “A statement, included in an aspect, that defines the joinpoints where the
associated aspect advice should be executed.” Point-cuts can specify join-points in several
ways, one of which is using a wildcard specified with an asterisk (*). Using the keyword
“within” will specify all join-points located within the specified data type (which can also
contain wildcards). Finally, point-cuts statements can be combined via the Boolean operators
&& (and), || (or), and ! (not). An example of a point-cut is shown in Figure 3 below.
Figure 3: The implementation of a point-cut and how it becomes associated with advice
Figure 3 displays part of an aspect implementing the logging concern from Figure 1. In Figure 3,
the point-cut PublicMethods is declared as all public method calls with any return-type and any
argument list. The first advice (which calls Logger’s BeginLog method) specifies that it be
inserted before any join-point that matches the PublicMethods point-cut. The second advice
specifies that it be inserted after any join-point that matches the PublicMethods point-cut.
Lastly, “thisjopinpoint” specifies the location of the join-point that was reached and is useful for
logging using aspects.
Aspect-oriented programming wouldn’t be possible without a program called an “aspect-
weaver.” This program performs the process of “weaving” advice into a software system at
join-points that match each advice’s point-cuts. Weaving is performed in one of four ways:
producing source-code with the advice weaved in, weaving advice in at compile-time to produce
a system with the advice built-in, weaving advice in at run-time dynamically, or sub-classing
those classes which contain aspects and using the child classes in place of their parents. Link-
time weaving is most commonly used because it has lower overhead than weaving advice at run-
time, but weaving at run-time is more flexible. Sub-classing classes with aspects results in
performance comparable to link-time weaving but is easier to use for debugging purposes.
Aspect - A Better Description
With the AOP terms discussed above, a clearer and more correct description of an aspect can be
given. An aspect is “a program abstraction that defines a cross-cutting concern” as a
collection of inter-type declarations, advice, and point-cuts specifying where each advice should
be weaved into a system. By using aspects correctly, complete separation of concerns can be
achieved in a system.
Aspect-Oriented Software Engineering
According to , “the notion of concerns is one that really comes from the system requirements.
Therefore, it makes sense to adopt an aspect-oriented approach at all stages of the system
development process”. Thus, aspects must be identified and isolated in each part of software
development in the software lifecycle – in other words, in the requirements, design, and
implementation phases. The testing and maintenance phases are affected by the changes to the
earlier phases, so they must be adapted to become aspect-oriented as well.
Recall that requirements given by a stakeholder reflects that stakeholder’s concerns for the
system. It is suggested in  to “think of a system that supports different stakeholder concerns
as a core system plus extensions.” Basically, concerns that are shared among all stakeholders
compose the core system while the remaining concerns are each extensions to the core system.
This method of arranging requirements results in separation of concerns at the earliest part of the
software engineering lifecycle, since extensions that would cross-cut are already separated from
the core system. In addition, this arrangement can persist through the design and implementation
phases as well since “aspects are a way to implement these extensions and they can be composed
with the core system functionality using … weaving…”
When the design phase is entered, the extensions to the core system need a way to be represented
separately from the core system. “During the development of use case models, you should look
for common features and… structure the use cases as core cases plus extensions. Cross-cutting
features…can also be represented as extension use cases.” Thus, aspects can be captured in
use case models by treating them as an extension of a core use case.
When system design begins after the development of use cases,  suggests a process for
designing a system in an aspect-oriented manner. First, the core system should be designed (no
extensions yet). Following this, extensions should be examined to identify aspects, then the
design of those aspects should commence. Once the pieces of the system have been designed,
the core system needs to be analyzed to locate join points for the aspects. Then, any aspect-
oriented conflicts (two aspects specifying the same point-cut, for example) should be found and
resolved. The final step identified by  is defining naming standards for the system so there are
no accidental point-cut matches (like from using wildcards). By following this process, aspects
can be easily represented in the system design.
Aspect-oriented approaches to class diagrams have also been developed. According to , the
particular UML variation shown in Figure 4 allows specification of an aspect and join-points
stating where the aspect’s advice needs to be included in the core system.
Figure 4: A UML variation of specifying aspects and their (broad) point-cuts 
As Figure 4 shows, aspects are identified by the stereotype <<aspect>>. Broad, module-level
point-cuts for an aspect are specified by using UML notes on the advice they relate to and by the
stereotype <<joinpoint>> inside each note. Thus, aspects and their point-cuts are represented in
a meaningful way in the design phase, and they’re still represented as separate from the core
Whether taking an aspect-oriented approach to implementation or not, developing the core
system is the same. However, in an aspect-oriented implementation, each extension is
implemented separately as an aspect using an aspect-oriented language extension such as
AspectJ. Then, to compile the final system, the code must first be passed to an aspect-weaver
and then to the compiler.
Since advice in an aspect is weaved into various join-points in the core system, testing an aspect-
oriented system becomes complicated. Black-box testing is “no different than for any other
system”, because the system after weaving in aspects should be the same as a system
produced in a non-aspect-oriented way. However, program inspections, code walkthroughs, and
white-box testing become difficult or even impossible to correctly perform in an aspect-oriented
system without special programs to allow the viewing of system code after advice has been
Other problems with testing aspect-oriented systems include determining how to test advice with
a dynamic point-cut, determining what “test coverage” means exactly, and how to test the effects
of aspects sharing the same join-point. These problems must be alleviated if aspect-oriented
software development is to become a more widespread practice.
Because an aspect-oriented approach to system development ideally encapsulates all of a cross-
cutting concern’s code into that concern’s aspect, maintenance is simplified. If a requirement
changes, it’s easy to make the required changes in implementation. After determining the
concern that requirement is part of, a maintainer can go to the module for that concern and
change its code to reflect the changed requirements. There is no need to search through all of the
code to determine all the locations at which a cross-cutting concern is implemented. This results
in a great amount of savings in time, effort, and most importantly money.
Another consideration in the maintenance phase is when methods in the core system change. If
only the methods were changed, point-cuts may become invalid and functionality may be lost.
Thus, when methods in the core system change, a maintainer must check for any affected point-
cuts and make appropriate changes to them.
In summary, some shareholder concerns are inherently cross-cutting – they become scattered
among and tangled with other concerns in the system. Separating these concerns is ideal for a
higher-quality software system. The concepts of an aspect, what it means to be aspect-oriented,
and how to encapsulate cross-cutting concerns were introduced in the paper “Aspect Oriented
Programming,” and approaches to encapsulate cross-cutting concerns in the requirements and
design phases of the software lifecycle soon followed. As a result of this complete separation of
concerns, a system can become functionally cohesive and possess the benefits of high
maintainability, understandability, adaptability, and extensibility (among others). However,
testing aspect-oriented systems is problematic and has many questions unanswered, even with
available tools. There is great promise these issues will be resolved, since aspect-oriented
software development is young and still ever-changing.
 Sommerville, I. (2011). Aspect-Oriented Software Engineering. Retrieved from
 Tekinerdogan, B. Separating Software Engineering Concerns: Introduction to AOSD.
Retrieved from http://trese.cs.utwente.nl/taosad/e-tutorial.htm
 Kiczales, G., Lamping, J., Mendhekar, A., Maeda, C., Videira Lopes, C., Loingtier, J.-M.,
Irwin, J. (1997). Aspect-Oriented Programming. Proceedings of the European Conference on
Object-Oriented Programming, 1241, 220-242.
 Filman, R. & Friedman, D. (2001). Aspect-Oriented Programming is Quantification and
Obliviousness. Workshop on Advanced Separation of Concerns, OOPSLA 2000. Retrieved
 Whitney, R. (2003). AspectJ Syntax. Retrieved from
 Cohen, T. & Gil, J. (2004). AspectJ2EE = AOP + J2EE. Towards an Aspect Based,
Programmable and Extensible Middleware Framework. Retrieved from