- Software Development and the Object-Oriented Paradigm
- The Case for Aspects
- What Is an Aspect?
- Why Consider Aspects in Analysis and Design?
- Aspects and Other Concerns
- The Theme Approach
- Applying the Theme Approach
- Theme: Symmetric or Asymmetric?
- Fitting Theme into Your Existing Development Process
- What About Implementation?
- Summary
Aspects and Other Concerns
In the world of aspect-oriented language development, aspects have taken on different forms. Two are most prominent: the asymmetric and the symmetric approaches.
Asymmetric Separation
In the asymmetric school of thought, aspects are separate from the core functionality of a program. Aspects are encoded as events that are triggered before, after, or as a replacement for certain other events, or in certain situations are located in the core. They describe additional dynamic behavior of a system that will have an effect on the core functionality. In a distributed system, for instance, there may be a collection of domain-specific objects that need to be managed in terms of distribution, synchronization, and transaction management.
The core contains the structure and behavior relevant to the domain functionality of the system. Separate from that core are aspects like the distribution of the objects in the system, the synchronization scheme associated with the methods belonging to those objects, and the wrapping of a set of operations into a single transaction. These are described in a separate module (each in its own aspect) and are invoked at certain strategic points in the execution of the core of the program. For instance, before certain methods are executed, the synchronization aspect may be used. Or, transaction-handling processing is initiated before and after the set of operations that make up a single transaction. In our banking example, as illustrated in Figure 1–2, the core is the set of banking-specific classes, and the aspect is a separate transaction handling entity.
Figure 1–2 Aspects and core in the asymmetric paradigm.
At a conceptual level, aspects have two important properties in this scheme. First, the aspect will only be triggered because of some execution in the core—for example, transaction handling is required only when changes are made to the balances of accounts. Second, the aspect is highly likely to be triggered in many parts of the system—it really is not generally all that useful to separate design/code into an aspect if it is executed in only one part of a system.
Table 1–1 provides definitions of the terms as typically used in this paradigm.
Table 1–1 Definition of Terms in the Asymmetric Separation Paradigm
Term |
Description |
Crosscutting |
Concern behavior that is triggered in multiple situations. |
Advice |
The triggered behavior. |
Aspect |
The encapsulation of the advice and the specification of where the advice is triggered. |
Core |
The traditional object-oriented part of the system to which aspects are applied. |
Joinpoint |
A possible execution point that triggers advice. |
Pointcut |
A predicate that can determine, for a given joinpoint, whether it is matched by the predicate |
Weaving |
Applying the advice to the core at the joinpoints that match the pointcut statements in the aspects. |
Symmetric Separation
In the symmetric separation model, in addition to the modularization of aspects, the core as described above is also analyzed for further modularization. Consider the core banking system from Figure 1–1. This example illustrates a small amount of real banking functionality with three basic features or concerns: transferring funds between two accounts, applying charges to an account, and applying interest to an account. In a real banking system, not only are there many other features, but these three features are subject to a significant number of banking rules. These rules depend on many different properties, such as the type of account, type of customer, legal and tax concerns (national/EU or state/federal, etc.), and so on. Figure 1–3 illustrates how it is possible that each feature is likely to result in many other methods that are likely to have an impact across the core set of banking classes.
Figure 1–3 Multiple concerns in the asymmetric core.
Figure 1–3 necessarily depicts just a small proportion of the possible impact of each of these three features on the classes. As you can see, there are multiple methods in the account classes that handle the business rules. The , , and classes all have many methods related to checking charges and checking interest. It may appear as if those could just be swept into the superclass. Unfortunately, that’s not the case. Each of the accounts handles those rules very differently, and so the functionality has to be present in each of them.
We hope you can visualize the potential real impact of including the full behavior not just of these three features, but also of all banking features on the core system. In the symmetric paradigm, different features of the system can be modularized into separate programs, as illustrated at the design level in Figure 1–4.
Figure 1–4 Separation of different features in the symmetric paradigm.
An entire system is therefore made up of bits of separate functionality that could be thought of as features or concerns. These can then be recombined in various ways to form a functioning whole. With this approach, a set of distributed objects would be formed by composing bits of basic object functionality together with bits of distribution functionality and synchronization functionality and transaction functionality.
At first glance, the duplication present in the symmetric approach looks as if it actually worsens scattering. For instance, all of the concerns except for the Transaction Management concern in Figure 1–4 have an class as well as a class, a class, and a class. This duplication is required in the symmetric approach in order to provide a complete view of the system from the perspective of a particular concern. The completeness of the view enhances separate understandability of a particular concern in the system.5 This understandability is achieved through increases in locality: Only and all relevant functionality for a concern is present within the concern module. Concern maintainability is also considered enhanced because of this functional locality. It is true that altering every method belonging to a class would require visiting many concerns, but since maintenance efforts are often performed to address particular concerns, the locality of all concern functionality within an identifiable group of modules is actually a help to system maintainability.
Of course, the symmetric approach can be applied on a continuum. It is unnecessary to keep minute concerns separate, just as it is unnecessary to bundle all the core concerns together. This spectrum is one that the developer is encouraged to explore, as each extreme has its own trade-offs and advantages.
The terms for the symmetric approach are given in Table 1–2. Notice that the terminology for this approach is different from the asymmetrical approach described above. Crosscutting, for instance, takes a wider stance: that it is widely triggered functionality, but also that structure and behavior (concepts) related to a particular concern are scattered throughout the system.
Table 1–2 Definition of Terms in the Symmetric Separation Paradigm
Term |
Definition |
Concern |
Some "kind" of functionality in your system. This could be a feature or a type of processing. |
Crosscutting |
A concern triggered in multiple situations or whose structure and behavior are scattered across the code base and tangled with code related to other concerns. |
Composition |
Combining the separately implemented concerns to form a functioning system. |