Home > Articles

  • Print
  • + Share This
This chapter is from the book

What Is an Aspect?

Simply put, an aspect is a particular kind of concern. A concern is any code related to a goal, feature, concept, or "kind" of functionality. An aspect is a concern whose functionality is triggered by other concerns, and in multiple situations. If the concern was not separated into an aspect, its functionality would have to be triggered explicitly within the code related to the other concern and so would tangle the two concerns together. Additionally, because the triggering is in multiple places, the triggers would be scattered throughout the system.

There are many examples of behavior like this—indeed, any functionality that has policies that need to be carried out in different modules of an object-oriented code base are likely candidates.

We’ve already described transaction management as an example of such code. Another typical example is logging or tracing code, since to add tracing code to a system, many locations must be modified, and every time the tracing scheme is changed, all those locations have to be altered. Another example is synchronization code, which is painful to implement, since it requires a developer to visit each method to be synchronized and add the necessary locking and unlocking functionality. Any code that may be needed in multiple places has the potential to be problematic. Having a programming model that means such code only needs to be written once and is in only one place when it requires change or deletion provides an obvious gain for the developer.

Aspects are not just a neat trick for adding logging or synchronization or other simple functionality. Such an assumption would be analogous to thinking of object-orientation as simply a means of organizing source code files. Aspects are a programmatic construct in and of themselves. Aspects provide active support, not just textual code manipulation, for separating concerns in source code. Aspects have been applied to far more complex crosscutting concerns than synchronization, logging, and tracing. For example, they have been applied in operating systems as a way to encapsulate and improve their performance.4

Let’s look at a small example. In any banking system, almost all changes to the balance of an account affect more than one place—for example, transferring funds requires debiting one account and crediting another; interest to be credited to a customer account implies a liability to the bank’s ledger (its own account); charges on a customer account imply a corresponding bonanza to the bank’s ledger. These are classic examples of transactions that must complete in entirety to be valid. Figure 1–1 illustrates simplified code for these examples.

Figure 1.1

Figure 1–1 Transaction handling occurring in multiple places.

In Figure 1–1, each of the places where transaction handling occurs in each sequence of actions is circled. As you can see, transaction functionality is present in multiple places in the code. Because transaction handling is triggered in different situations by other concerns (such as money transfer, account updating, interest charging), transaction handling should, for this system, be implemented as an aspect.

Aspects can also be evident at earlier phases of the development lifecycle. Aspects manifest in requirements as behavior that is described as being triggered by many other behaviors. Requirements that described the banking system, for instance, would have mentioned that transaction handling was required for a range of activities, including managing interest, transferring money, and so on. Aspects manifest in UML designs as behavioral design elements that are triggered by other behavioral design elements in the UML models. Designs that describe the banking system would have transaction behavior tangled in the behavioral models for the banking activities.

  • + Share This
  • 🔖 Save To Your Account