Section 8.4. EVALUATION


8.4. EVALUATION

This section discusses how CAESAR copes with the problems outlined in Section 8.2. In addition, we elaborate on how CAESAR'S explicit aspect instantiation and deployment relate to AspectJ-like languages, where aspects are only implicitly created and which do not have a notion of aspect deployment.

8.4.1. Problems Revisited

Recall that we identified the following problems for 'conventional' AOP in Section 8.2:

  1. Lack of support for multi-abstraction aspects.

  2. Lack of support for sophisticated mapping of aspect abstractions to base classes.

  3. Lack of support for reuse of aspect bindings.

  4. Lack of support for aspectual polymorphism.

In the following, we explain how each of these problems is solved in CAESAR.

8.4.1.1 Multi-Abstraction Aspects

As was shown in the code in Listings 8-3, 8-4, and 8-5, each abstraction in the vocabulary of the world as it is decomposed from the point of view of an aspect is defined in its own full-fledged module with a well-defined interface. Methods in the interface of one abstraction can be called by methods of other abstractions within the same aspect or from the outside. For example, consider the call of Subject.notify(...) in the implementation of ObserverProtocolImpl in Listing 8-4, or the invocation of CO.THIS.addObserver(...) in Listing 8-9.

This finer-grained modularization of the aspect itself allows the run-time system to dispatch methods based not only on the instance of the aspect but also on the particular abstraction in execution. Consider, for example, the getState() method in the definition of Subject, which was implemented differently for point-subjects and for line-subjects, while being used uniformly in the update logic (cf. Listing 8-5). As was pointed out in Section 8.2, the same polymorphism would not be possible if there were only aspect-level methods. Furthermore, due to the incorporation of virtual classes, it is easy to encode different variants of a multi-abstraction aspect, as illustrated in Listing 8-12.

Let us now consider the issue of defining state for the individual abstractions pertaining to an aspect. The examples in the previous section show that each abstraction in the modular structure can declare its own state, e.g., observers in Subject. Hence, there is no need for defining data structures that "globally" maintain aspect-related state of all base objects in a single place, such as perSubjectObservers in Listing 8-1. Similarly, state can be added to the abstractions at the binding side, such as the count field in Listing 8-12.

8.4.1.2 Sophisticated Aspect to Base Class Mapping

In our model, bindings are Java classes with some additional features. As such, the definition of mappings from aspect abstractions to the classes of a base application can make use of the full expressiveness of a general purpose OO language. There is nothing to prevent a CAESAR programmer from coding any mapping, no matter how sophisticated (cf. the example at the end of Section 8.3.3, see also [19] for more examples).

8.4.1.3 Reusing Aspect Bindings

Different weavelets can combine an aspect binding with different aspect implementations. On the other hand, different weavelets can combine (and reuse) a particular aspect implementation with multiple different bindings. For example, we can combine the observer protocol binding to JButton and MyActionListener with the LinkedList or the AsynchronousUpdate observer implementation. On the other hand, we can combine the same observer implementation, say AsynchronousUpdate, with multiple different bindings, e.g., to JButton/MyActionListener and ListModel/JList. Consequently, one can define functionality that is polymorphic with respect to (a) aspect implementations by being written to a certain aspect binding type, (b) aspect bindings by being written to a certain aspect implementation type, or (c) both of them by being written to an ACI.

8.4.1.4 Aspectual Polymorphism

As discussed in Section 8.3.7, our approach does support aspectual polymorphism. For example, the modify(Point p[]) method in Listing 8-10 is polymorphic with respect to aspects that might be defined in the future. It is even possible to run the same method concurrently within two different threads with and without the logging aspect.

8.4.2. Explicit Versus Implicit Aspect Instantiation/Deployment

The question we pose here is: How does our notion of explicit aspect instantiation and deployment relate to AspectJ-like languages, within which aspects are only implicitly created and which do not have a notion of aspect deployment? In AspectJ, aspect instantiation can be controlled by means of the aspect modifiers isSingleton (this is the default), perThis/perTarget, and percflow/percflowbelow. In CAESAR, these aspect instantiation strategies turn out to be special cases or "patterns" of the more general model in CAESAR.

Table 8-1 describes how the AspectJ instantiation strategies can be simulated in CAESAR. The isSingleton case is obvious. The perThis modifier can be simulated by creating a wrapper class and using wrapper recycling to refer to the state that is associated with each point. Simulating perTarget is identical to perThis, except that we would have to exchange this(p) by target(p). More interesting is AspectJ's percflow modifier, which means that an instance of the aspect is created for each flow of control of the join points picked out by the annotated pointcut. The semantics of percflow can be simulated by using a deployment aspect ADepl that uses dynamic deployment at the respective starts of control flow.

Table 8-1. Aspect Instantiation in AspectJ and CAESAR

AspectJ

CAESAR

 aspect A isSingleton { State s; } aspect A perThis(pointChanges) {   pointcut pointChanges() :      call (Point.setX(int));   State s;   after(Point p): pointChanges() &&     this(p) { ...s...} } aspect A percflow(pointChanges) {   pointcut pointChanges():      call (Point.setX(int));   State s;   after(): somePointCut() { ... } } 

 deploy class A {State s;} deploy class A {   class PointWrapper     wraps Point { State s}   after(Point p):     call(Point.setX(int)) &&      this(p) {       ...PointWrapper(p).s; ... } class A {   State s;   after(): somePointcut() { ... } } deploy class ADepl {   around():     call (Point.setX(int)) {       deploy(newA()){proceed();} } 


What do we gain if all the cases in Table 8-1 can already be handled very well by AspectJ? Recall that AspectJ instantiation strategies are just special cases of a more general model in CAESAR. This has two implications. First, we do not need special new keywords to express the semantics of AspectJ instantiation. Second, and more importantly, our model allows us to express instantiation and deployment semantics that cannot easily be expressed in AspectJ.

When using AspectJ's perThis of perTarget modifiers, state can be only associated with objects that are caller or callee, respectively, in a pointcut. In CAESAR, state can be associated with arbitrary objects and arbitrary relations between objects. For example, we could associate state with every pair of this and target, or with any argument of a method call. In the percflow case, we can not only simulate the AspectJ semantics but also express more sophisticated behaviors, such as deploying an instance of an optimization aspect only if the number of calls to the method to be optimized is executed more than a certain number of times.



Aspect-Oriented Software Development
Aspect-Oriented Software Development with Use Cases
ISBN: 0321268881
EAN: 2147483647
Year: 2003
Pages: 307

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net