Simon Denier
email: simon.denier@emn.fr

Pierre Cointe
email: pierre.cointe@emn.fr

Expression and Composition of Design Patterns with AspectJ

Keywords: Design Patterns, Aspects, Composition, Interaction, Reusability. MOTS-CLÉS : motifs de conception, aspects, composition, interaction, réutilisation

 is the first extensive study of patterns aspectization with AspectJ. We notice some AspectJ idioms are needed in order to implement object relationships. We give a more reusable VISITOR pattern. We highlight a reusable composition of COMPOSITE and VISITOR patterns and expressive interactions of the OBSERVER pattern with a tree structure. We thus show that modularization by aspects helps composition of design patterns.

 est la première étude extensive de l'aspectisation des motifs avec AspectJ. Nous remarquons que AspectJ nécessite des idiomes afin de pouvoir implémenter les relations interobjets. Nous donnons une version plus réutilisable du motif VISITOR. Nous soulignons la composition réutilisable des motifs COMPOSITE et VISITOR, ainsi que des interactions expressives entre un motif OBSERVER et une structure en arbre. Nous montrons ainsi que la modularisation par les aspects facilite la composition des motifs de conception.

Introduction

Design patterns [START_REF] Gamma | Design Patterns: Elements of Reusable Object-Oriented Software[END_REF] are well-known couples of problemssolutions for software engineering. They give some clues on benefits and tradeoffs of design implementation in object-oriented languages. They offer abstract descriptions that cover the gap between the model and the implementation, facilitating a mutual understanding. They are supportive of code micro-architectures, which enable variability and evolutivity.

However, object-oriented implementations of design patterns have failed in two ways. First, it is hard to maintain a link between the model and the implementation. Some concrete elements are hardly modularized and tend to be lost in the code. The pattern is said to vanish [START_REF] Soukup | Implementing patterns[END_REF] -in a modern stance, it lacks traceability. Second, lack of modularization means design patterns implementations are hardly reusable [START_REF] Tatsubori | Programming support of design patterns with compile-time reflection[END_REF][START_REF] Albin-Amiot | Idiomes et patterns Java : Application à la synthèse de code et à la détection[END_REF].

Language features impact design patterns implementations, to the point where some patterns have built-in support and seem straightforward [START_REF] Chambers | A debate on language and tool support for design patterns[END_REF]. Aspect-oriented languages provide new mechanisms to enable modularization of crosscutting concerns [START_REF] Kiczales | Aspect-Oriented Programming[END_REF]. Such mechanisms can capture patterns or help to modularize them. [START_REF] Hannemann | Design pattern implementation in Java and AspectJ[END_REF] provides the first extensive study of design patterns implementation with AspectJ, an extension of Java for aspectoriented programming [START_REF] Kiczales | An overview of AspectJ[END_REF][START_REF] Colyer | eclipse AspectJ[END_REF]. It claims that most design patterns from [START_REF] Gamma | Design Patterns: Elements of Reusable Object-Oriented Software[END_REF] get benefits from aspectization, in particular better modularity, and gives some insights on their crosscutting nature.

We review the aspectized patterns from [START_REF] Hannemann | Design pattern implementation in Java and AspectJ[END_REF] and get the feeling that these implementations present programming idioms for AspectJ. These idioms capture objects relationships -such as a design pattern structure -and implement it in the aspect. In our opinion this shows that the aspect model in AspectJ is heterogeneous with respect to an object model: aspect instances can not be controlled as object instances and this hampers the use of AspectJ. Such critics have been made in [START_REF] Mezini | Conquering Aspects With Caesar[END_REF]. However, we also find that AspectJ mechanisms allow to bypass these object idioms and provide better implementations for the VISITOR pattern.

Another topic of interest is the composition of design patterns. As examplified in the Java AWT framework, such compositions are frequent and their understanding can be crucial. This includes patterns making use of others in their implementation as well as interaction between two patterns. To our knowledge few work has studied this field: most prominent include [START_REF] Gamma | Design Patterns: Elements of Reusable Object-Oriented Software[END_REF] (section "Design pattern relationships") and [START_REF] Zimmer | Relationships between design patterns[END_REF], who proposes a classification of the different kind of relationships between design patterns. Composition leads to the pattern density phenomenon: patterns provide leverage but their implementations become so entangled that it is nearly impossible to think of a pattern alone and that the program becomes hard to change [START_REF] Gamma | JUnit: A Cook's Tour[END_REF].

The modularity gain from aspects promises a better understanding of composition and interactions between design patterns. We start to evaluate some composition cases, such as a well-known collaboration between COMPOSITE and VISITOR patterns, and "unforeseen" interactions with an OBSERVER pattern. We highlight the reusability and expressiveness of such compositions. We also experiment with objectaspect and aspect-aspect compositions of design patterns, to once more reveal the heterogeneity between aspects and objects in AspectJ.

Section 2 provides a quick overview of aspects concepts and some specificities of AspectJ. Section 3 reviews the usage and idioms of AspectJ to implement a design pattern with the OBSERVER pattern as example. We also review the DECORATOR pattern, which departs from idioms with benefits and drawbacks. We provide a new implementation of the VISITOR pattern, which improves on reusability and genericity, literally standing between a pattern and multiple-dispatch mechanism. Section 4 examines two cases of composition. First, we provide a reusable composition of COMPOSITE and VISITOR patterns. Second, we study new expressiveness of the OBSERVER pattern in face of a tree structure composed by COMPOSITE and DECORATOR, both as objects and as aspects. Section 5 gives related work and Section 6 concludes.

Overview of Aspects and AspectJ

We begin with a quick overview of aspects concepts and illustrations in AspectJ, an extension of Java. For readers interested by AspectJ, there are numerous ressources [START_REF] Kiczales | An overview of AspectJ[END_REF], including book [START_REF] Colyer | eclipse AspectJ[END_REF] and online sites 1 .

The main intuition behind AOP is to introduce a join point model defining interesting events during execution of a program. These can be method call, method execution, constructor call, field access. . . A pointcut language selects specific join points, based for example on class and method name. In AspectJ, pointcuts can expose some of the execution context via variables. They can also be composed with logical operators (and, or, not). An advice language defines code to be ran at join points captured by pointcuts. In AspectJ, an advice is linked to a pointcut and parameterized by pointcut variables. Apart from this declaration, advice are defined like methods. An aspect is primarely a modular unit composed of pointcuts and advice. Like a class, it can contain ordinary member definitions such as fields and methods. An AspectJ aspect declaration has a form similar to that of a Java class declaration. Finally, the process by which an aspect is "plugged" into a program is called weaving. AspectJ allows weaving at compile-time or load-time, but not runtime.

For the purpose of this paper, there are two specificities of AspectJ we must review. First are Inter-Type Declarations (ITDs), which are a subset of structural reflection. They allow to introduce new members inside existing classes without modifying class source. A noteworthy feature of AspectJ is that such introductions can be made in combination with an interface: any class implementing this interface will "inherit" these new members. This makes ITDs akin to mixin inheritance or traits [START_REF] Denier | Traits Programming with AspectJ[END_REF].

Second is the instantiation model of aspects in AspectJ. Like classes, aspects define instances to operate at runtime. Unlike classes, users do not explicitely control when an aspect instance is created and its scope of execution. Instead, this is an option to be chosen in the aspect declaration. Figure 1 shows two such options. By default an aspect defined a singleton instance, which runs on any target join points. But the aspect can also declare a ♣❡rt❤✐s✭❛P♦✐♥t❝✉t✮ modifier: in this case one aspect instance will be lazily created for each object crosscutted by ❛P♦✐♥t❝✉t. Whenever a join point is picked up inside one of these objects, its associated aspect instance will run the advice. Such a per-object aspect instance will never run advice outside of its object context. We retain that the AspectJ instantiation model controls both the creation and the scope of an aspect instance.

Expression of Single Design Patterns

An examination of the catalog of aspectized design patterns from [START_REF] Hannemann | Design pattern implementation in Java and AspectJ[END_REF] reveals many similarities between implementations. These similarities are more complex than straightforward language use and seem rather specific to AspectJ. We abstract them as idioms, that is "good practice" particular to AspectJ. Prominent idioms for design patterns implementation in AspectJ are:

-an aspect modularize the whole design pattern (including roles and collaborations), possibly deferring specialization to subaspects and classes;

-roles are declared by Java interfaces;

-relationships between roles can be implemented with Inter-Type Declarations (a subset of structural reflection) or centralized by the aspect in a single structure; -collaborations are a mix of pointcuts, advice and regular methods. Section 3.1 exposes such idioms for the OBSERVER pattern. The use of interfaces as roles and the centralized structure for relationships are especially idiomatic to [START_REF] Hannemann | Design pattern implementation in Java and AspectJ[END_REF]. Overall, these idioms allow to implement objects relationships inside an aspect.

3.1. Anatomy of an Aspectized Pattern: the OBSERVER Pattern [START_REF] Gamma | Design Patterns: Elements of Reusable Object-Oriented Software[END_REF] cites the OBSERVER pattern as useful to:

"define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically."

We choose this particular pattern as it is: a well-known design pattern; an example of the benefits of aspects for pattern implementation; an example of AspectJ mechanisms and idioms. To describe the AspectJ-based implementation, we follow three sections in [START_REF] Gamma | Design Patterns: Elements of Reusable Object-Oriented Software[END_REF] which best relate to a general implementation of a design pattern: Structure, Participants and Collaborations. Figure 2 shows a reusable implementation of the OBSERVER pattern, which differs slightly from the one found in [START_REF] Hannemann | Design pattern implementation in Java and AspectJ[END_REF]. In particular, we present a solution using Inter-Type Declarations (ITDs). Figure 3 shows how to specialize this implementation for use.

First, a whole design pattern (including roles and collaborations) can be modularized in a single aspect. Some of them, such as the OBSERVER pattern (Figure 2), are reusable and can be specialized by aspect extension and class inheritance (Figure 3).

Participants or Roles, quickly describe entities involved in the pattern solution and their responsibilities. As such, they are interesting in order to trace and to understand how classes are involved with the pattern. In AspectJ, Java interfaces are used to define such roles (lines 3 and 8). Java interfaces are transversal to the inheritance hierarchy, so that it does not need modification. Also, AspectJ allows to apply roles (interfaces) from aspects (Figure 3, lines 2 and 3).

Structure is primarely a representation of Relationships between roles, such as inheritance and aggregation. Most design patterns work by decoupling concerns and assigning them to different roles, with an indirection. Then, relationships between roles must be defined to allow them to collaborate. A typical relationship, aggregation, is for a role instance to hold a reference in a field to another role instance. For example, subjects in the OBSERVER pattern hold a list of reference to their observers.

ITDs are a straightforward way to implement such relationships. For example, the list of references to Observers is implemented in ❙✉❜•❡❝t interface line 4 (Figure 2).

Line 5 shows the introduction of an accessor. After compilation and weaving, all classes implementing this interface will get these implementations. A possible problem is that public ITDs (line 5) can conflict with elements from target class.

Another solution to implement relationships while avoiding ITDs conflict is to centralize them in a single structutre within the aspect. For example, the OBSERVER aspect in [START_REF] Hannemann | Design pattern implementation in Java and AspectJ[END_REF] holds references from all subjects to their observers: each subject is a key to its list of observers in a ❍❛s❤▼❛♣. The use of hash tables to centralize aggregation relationships is idiomatic in [START_REF] Hannemann | Design pattern implementation in Java and AspectJ[END_REF].

Either ITDs or aspect centralization need some way to manage relationships: the registration process (Figure 2, lines 20 to 22, and Figure 3, lines 7 and 8) shows how these can be managed by pointcuts and advice.

Collaborations describe how roles work together to fulfill the pattern intent. Collaborations are usually defined in object-oriented languages by message passing and method definition. Aspects tend to partially replace methods with advice and method calls with pointcuts. Figure 2 shows such a case lines 13 to 17: the st❛t❡❈❤❛♥❣❡s pointcut capture notification points and the advice performs the notification process. Then, the task is fulfilled by calling ✉♣❞❛t❡ on observers. The dependency extraction which results from pointcuts is a key benefit from aspects. The intent of the DECORATOR pattern, as defined in [START_REF] Gamma | Design Patterns: Elements of Reusable Object-Oriented Software[END_REF], is to: "attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality." Figure 4 gives an example of the DECORATOR pattern from [START_REF] Hannemann | Design pattern implementation in Java and AspectJ[END_REF]. Many decorators can be defined on the same join point, ordered by precedence and applied or removed at weaving. With respect to the object-based implementation, the benefits are obvious: 1) only decorated methods are advised, eliminating the "implementation overhead" [START_REF] Bosch | Design Patterns as Language Constructs[END_REF] of numerous forwarding methods;

2) there is no indirection for non-decorated methods, reducing the runtime cost;

3) there is no need to insert a Decorator instantiation.

This solution is great when subclassing is not allowed or to apply a DECORA-TOR pattern on the whole program. However, with respect to the intent above, this implementation does not allow to dynamically attach a decorator to one object.

We propose an extension in Figure 5. The main idea it that each instance has an ❛❝t✐✈❡ state (line 2), which controls the decorator behavior (line 8). A key construct of this implementation is the ♣❡rt❤✐s modifier (line 1): it allows to associate one aspect instance to each ❈♦♥❝r❡t❡❖✉t♣✉t object, effectively defining one ❛❝t✐✈❡ state per object. In any case, ♣r♦❝❡❡❞ allows the action to finally proceed to the decorated object (line 10). ❞❡❝♦r❛t❡ and str✐♣ methods from ❇r❛❝❦❉❡❝♦r❛t♦r aspect allow to dynamically apply the decorator behavior (line 13). -no dynamic reordering of decorators, since precedence is statically defined;

-no recursive composition (a ❇r❛❝❦❡t❉❡❝♦r❛t♦r around a ❇r❛❝❦❡t❉❡❝♦r❛t♦r around a . . . ), since we can not instantiate an aspect at will.

Contrary to the OBSERVER pattern and other patterns in AspectJ, the above DECO-RATOR pattern is less idiomatic: no role, no structure for relationships. In this case, the aspect is the decorator, whereas it tends to be an encapsulating module in other patterns. The reason is that ❛r♦✉♥❞ advice allows straightforward decoration, which considerably simplifies the implementation. The drawback, as seen above, is that it is not possible to get a full control on the instantiation and composition of decorators.

3.3.

Revisiting the VISITOR Pattern [START_REF] Gamma | Design Patterns: Elements of Reusable Object-Oriented Software[END_REF] announces:

"[Visitor can] represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates."

It is well-known as a replacement for multi-methods, or more precisely doubledispatch, in languages which do not support it.

The reusable VISITOR pattern in [START_REF] Hannemann | Design pattern implementation in Java and AspectJ[END_REF] follows the guidelines from Section 3.1. This primarely includes a ❱✐s✐t♦rPr♦❝♦❝♦• aspect, which defines roles-interfaces for Visitor, Node and Leaf (where nodes are nonterminal and leaves are terminal) and ITDs of ❛❝❝❡♣t✭❱✐s✐t♦r✮ in nodes in the usual way -◆♦❞❡✳❛❝❝❡♣t✭❱✐s✐t♦r✮ (resp. ▲❡❛❢✳❛❝❝❡♣t✭❱✐s✐t♦r✮) calls ❱✐s✐t♦r✳✈✐s✐t◆♦❞❡✭◆♦❞❡✮ (resp. ❱✐s✐t♦r✳✈✐s✐t▲❡❛❢✭▲❡❛❢✮). A first remark is that it does not use pointcut and advice -only ITDs. A second remark is that this visitor only distinguish two kinds of node, which severely restricts its genericity. This solution suffers from the same shortcoming than the object-oriented visitor: it does not allow to easily change the visited structure.

We propose in Figure 6 a more generic and reusable VISITOR pattern, which slightly differs in principle from the classic pattern. There is no more indirection by an ❛❝❝❡♣t method in ❱✐s✐t❛❜•❡◆♦❞❡. Two interfaces are still defined for roles (lines 2 and 3), but we do not discriminate between nodes at this level. We still use an ITD to introduce the ✈✐s✐t method in ❱✐s✐t♦r (line 4). The novelty is that we also define a pointcut, ✈✐s✐t, on this method (lines 5 and 6). The purpose of the ✈✐s✐t♦r pointcut and ♣❡rt❤✐s modifier is explained below. Figure 7 shows how such a visitor can be defined. It is broken up between the ❈♦✉♥t✐♥❣❱✐s✐t♦r class, which in particular defines state and accessors, and the ❈♦✉♥t✐♥❣❱✐s✐t♦r❇❡❤❛✈✐♦r aspect, which defines the behavior corresponding to the visited structure (see Figure 9 for structure definition). The ✈✐s✐t♦r pointcut (lines 7 & 8) targets the ❈♦✉♥t✐♥❣❱✐s✐t♦r class, so that an aspect instance of ❈♦✉♥t✐♥❣❱✐s✐t♦r❇❡❤❛✈✐♦r is created for each object (thanks to the ♣❡rt❤✐s modifier from Figure 6, line 1). The goal is to create an exclusive relationship between a visitor aspect and a visitor object: the aspect only crosscuts its associated object and can refer to it with ♠②❱✐s✐t♦r■♥st❛♥❝❡ (lines 9 to 11).

The purpose of the crosscutted ✈✐s✐t method defined in Figure 6 appears lines 13, 16 and 21: this join point creates a dynamic association between a visitor and a node, which is advised by ❈♦✉♥t✐♥❣❱✐s✐t♦r❇❡❤❛✈✐♦r. Dynamic dispatch occurs thanks to the ❛r❣s predicate, which works on dynamic types of parameters. The last advice shows a default behavior, crosscutting on any node which is not captured by the above advice. The use is simple: instantiate a ❈♦✉♥t✐♥❣❱✐s✐t♦r and traverse the structure with it, calling ✈✐s✐t on each node (see Figure 9). Notice that we make no hypothesis on how the structure is traversed and when the ✈✐s✐t method is called. Following [START_REF] Gamma | Design Patterns: Elements of Reusable Object-Oriented Software[END_REF], this can be the responsibility of the structure, the visitor (in non-terminal nodes) or an external iterator.

p u b l i c c l a s s C o u n t i n g V i s i t o r implements V i s i t o r { 2 p r i v

Synthesis on Aspects, AspectJ and Design Patterns

Apart from dependency inversion [START_REF] Nordberg | Aspect-Oriented Dependency Inversion[END_REF] and crosscutting modularization [START_REF] Hannemann | Design pattern implementation in Java and AspectJ[END_REF], new mechanisms (useful although not specific) which come with aspects can improve a whole design pattern solution. This is the case with the DECORATOR pattern and particularly with our new VISITOR pattern. In particular, pointcut predicates offer new expressiveness, especially on dynamic properties. Design patterns whose behavior change based on the dynamic context could be improve in the same way: this could include, for example, STRATEGY, COMMAND, or CHAIN OF RESPONSIBILITY patterns.

We notice that idioms primarely target roles and relationships. Then the pattern aspect works as a singleton. The aspectized DECORATOR pattern, which violates these idioms to simplify its implementation, suffer from problems on instantiation and composition. Finally, our new VISITOR pattern needs a dual definition of class and aspect in order to work: the visitor class can be created on will and provides the scope for the visitor aspect. These examples highlight the heterogeneous nature of aspect instances in AspectJ: they are hardly usable as normal object instances, which can hamper their own design. We believe this is one of the main weakness of AspectJ. However, this problem is rather specific to AspectJ and not to aspect languages in general.

Composition of Design Patterns

In this section we experiment two cases for composition of design patterns involving aspects. The first case aims at producing a reusable composition based on simple reusable patterns. We take COMPOSITE and VISITOR as they are often used together. The second case looks at interactions which can interest the OBSERVER pattern when dealing with COMPOSITE and DECORATOR patterns. However, we survey in this case the aspectual interactions with COMPOSITE and DECORATOR both as objects and as aspects. Indeed, we show that the AspectJ expression of these interactions depends on the aspect or object nature of the pattern implementation.

Composition of COMPOSITE and VISITOR Patterns

The intent of the COMPOSITE pattern, citing [START_REF] Gamma | Design Patterns: Elements of Reusable Object-Oriented Software[END_REF], is to:

"compose objects into tree structures to represent part-whole hierarchies.

Composite lets clients treat individual objects and compositions of objects uniformly."

The class structure is straightforward: the ❈♦♠♣♦s✐t❡ class subclasses and defines a one-to-many relation to a ❈♦♠♣♦♥❡♥t class. This allows recursive composition: a ❈♦♠♣♦s✐t❡ instance can hold references to any type of ❈♦♠♣♦♥❡♥t instances, including other ❈♦♠♣♦s✐t❡s. The ❈♦♠♣♦s✐t❡ class inherits the interface of ❈♦♠♣♦♥❡♥t but usually overrides each method in order to forward it to its children. Then, a method called on a ❈♦♠♣♦s✐t❡ recursively goes down until reaching non-Composite instances. In a language which lacks multi-methods, closures or first-order methods, this leads to implementation overhead as each method must define the same loop to forward itself. The goal of the aspectization (Figure 8) is to promote a reusable definition of the COMPOSITE pattern. Then, it can be applied on existing classes, removing the implementation overhead of defining the structure and the registration logic. To further reduce implementation overhead, it must also define a "forward loop" which can be parameterized by function. A solution is to combine the COMPOSITE pattern with a VISITOR pattern, which we overview in this section and the next one.

We start with the solution of [START_REF] Hannemann | Design pattern implementation in Java and AspectJ[END_REF], using interfaces for roles (lines 3 to 5), and the idiomatic centralized structure. Indeed the relationships between ❈♦♠♣♦s✐t❡ and their children are all stored in the ♣❡r❈♦♠♣♦♥❡♥t❈❤✐•❞r❡♥ map. For each ❈♦♠♣♦s✐t❡, the map stores a ❱❡❝t♦r of ❈♦♠♣♦♥❡♥t children (line 8).

In its solution, Hannemann then proceeds by defining a whole new ❱✐s✐t♦r inside its COMPOSITE pattern, copying but not reusing its genuine VISITOR pattern. We prefer to reuse our lighter, more generic solution. Thus, we simply include an interface to collaborate with the VISITOR pattern defined in Section 3.3. Collaborations need only one preliminary declaration: we declare a ❈♦♠♣♦♥❡♥t as a ❱✐s✐t❛❜•❡◆♦❞❡ for ❱✐s✐t♦r (line 22). r❡❝✉rs❡❆•• (lines 23 to 26) is an example of such a collaboration: it performs the call to ✈✐s✐t (which triggers the ❱✐s✐t♦r action) recursively on all subcomponents. Another collaboration, for example, is to make a simple forward, non-recursive, to children (the visitor will decide itself whether or not to perform a recursive visit). Figure 9 shows how to apply the COMPOSITE pattern and use it with a VISI-TOR pattern. We start with base classes ❚❡st❈•❛ss, ❚❡st▲❡❛❢, and ❚❡st❈♦♠♣♦s✐t❡ (lines 2 to 4 -the inheritance relationship is not mandatory). The ❚❡❛♠▼❛♥❛❣❡r aspect extends ❈♦♠♣♦s✐t❡Pr♦t♦❝♦• (line 7) to define a COMPOSITE pattern on these classes: it does so by matching each class with its role interface (lines 8 to 10). These are the only required steps to use ❈♦♠♣♦s✐t❡Pr♦t♦❝♦•.

From lines 13 to 17, we show typical tasks with a ❈♦♠♣♦s✐t❡: instantiation, child registration. Then we recurse over the whole structure, using the ❈♦✉♥t✐♥❣❱✐s✐t♦r defined in Figure 7, to count the number of nodes.

4.2.

The OBSERVER Pattern with DECORATOR and COMPOSITE Patterns [START_REF] Gamma | Design Patterns: Elements of Reusable Object-Oriented Software[END_REF] already cites the natural composition of DECORATOR and COMPOSITE patterns. They form together rich tree structures. Another case for composition is to plug an OBSERVER pattern on such a structure. With aspects, an ❖❜s❡r✈❡r can crosscut on the whole tree, adding some expressiveness hardly allowed by traditional object-based ❖❜s❡r✈❡r. The purpose of this section is to examine the expressiveness of AspectJ when composing the ❖❜s❡r✈❡r aspect with ❈♦♠♣♦s✐t❡ and ❉❡❝♦r❛t♦r, first as objects, second as aspects. This uncovers the fact that AspectJ needs to treat objects and aspects in different manner.

Some Examples of Tree-Wide Observation

In this section, we use a tree of ❋✐❣✉r❡s (in the context of a structured drawing program, for example) and the ❖❜s❡r✈❡r defined in Figure 3. We make the hypothesis we have some ❈♦♠♣♦s✐t❡❋✐❣✉r❡ and ❉❡❝♦r❛t♦r❋✐❣✉r❡ classes (Figure 10). We refer to [START_REF] Denier | Understanding Design Patterns Density with Aspects[END_REF] for a concrete case and the rationale behind such a composition. Obviously, we can make the ❋✐❣✉r❡❖❜s❡r✈❡r aspect notifies for any action in any ❋✐❣✉r❡s, including ❈♦♠♣♦s✐t❡❋✐❣✉r❡ and ❉❡❝♦r❛t♦r❋✐❣✉r❡ (Figure 10, la-bel A). This triggers redundant notifications. However, there are other possibilities to precisely customize the crosscut: 1) some notifications occur at the top level and do not need to be raised down in the tree -for example, ❈♦♠♣♦s✐t❡❋✐❣✉r❡ can make global notifications, regardless of its children (Figure 10,label B); 2) some notifications occur within tree leaves but need parameterization according to top level nodes -for example, ❉❡❝♦r❛t♦r❋✐❣✉r❡ in the path of action takes over notification following notification from its child (Figure 10,label C).

CompositeFigure

Following the above strategies, we can improve on the definition of a notification: first where and when do we notify; second which ❋✐❣✉r❡ is deemed responsible for the notification (it will be transmitted as a parameter of notification). We notice that strategies can be defined for each action on a case by case basis using aspects. 4.2.2. An Aspectual ❖❜s❡r✈❡r with ❉❡❝♦r❛t♦r and ❈♦♠♣♦s✐t❡ as Objects

The object-oriented solutions of DECORATOR and COMPOSITE patterns define a recursive control flow whenever a method is called on the tree. Indeed their basic principle for implementation of methods is to forward the message to their children. AspectJ can then crosscut the tree using its ❝❢•♦✇ constructs.

The strategy labelled B targets "top-level calls". The solution is straightforward and well-known in AspectJ. Oblivious to the type of figure crosscutted (whether a leaf figure, a ❈♦♠♣♦s✐t❡❋✐❣✉r❡ or a ❉❡❝♦r❛t♦r❋✐❣✉r❡, it will only catch the first call on a recursive control flow (not necessarily the tree root). The ❛❝t✐♦♥ pointcut below defines the target of notification. The t♦♣▲❡✈❡•◆♦t✐❢② pointcut implements strategy B and retrieves the figure responsible for the notification. In this case the figure is directly retrieved from the current join point.

♣♦✐♥t❝✉t ❛❝t✐♦♥✭✮✿ ❡①❡❝✉t✐♦♥✭✈♦✐❞ ❋✐❣✉r❡✰✳♠♦✈❡✭✳✳✮✮❀ ♣♦✐♥t❝✉t t♦♣▲❡✈❡•◆♦t✐❢②✭❋✐❣✉r❡ ❢✮✿ t❤✐s✭❢✮ ✫✫ ❛❝t✐♦♥✭✮ ✫✫ ✦❝❢•♦✇❜❡•♦✇✭❛❝t✐♦♥✭✮✮❀
At first glance the strategy labelled C follows the contrary line. The ❞❡❝♦r❛t❡❞❆❝t✐♦♥ pointcut takes care of join points which are beneath a ❉❡❝♦r❛t♦r❋✐❣✉r❡. However, the figure retrieved in this case is the figure underneath, not the ❉❡❝♦r❛t♦r❋✐❣✉r❡. This violates the definition of strategy C, which tells the ❉❡❝♦r❛t♦r❋✐❣✉r❡ is responsible when its children notify.

♣♦✐♥t❝✉t ❞❡❝♦r❛t❡❞❆❝t✐♦♥✭❋✐❣✉r❡ ❢✮✿ t❤✐s✭❢✮ ✫✫ ❡①❡❝✉t✐♦♥✭✈♦✐❞ ❋✐❣✉r❡✰✳s❡t❆ttr✐❜✉t❡✭✳✳✮✮ ✫✫ ❝❢•♦✇❜❡•♦✇✭❡①❡❝✉t✐♦♥✭✈♦✐❞ ❉❡❝♦r❛t♦r❋✐❣✉r❡✳s❡t❆ttr✐❜✉t❡✭✳✳✮✮✮❀
We need another solution for strategy C. The process is two-step. First we retrieve the top most ❉❡❝♦r❛t♦r❋✐❣✉r❡ (by definition of strategy C, the top most decorator is always responsible for other figures). ❞❡❝♦r❛t♦r❆❝t✐♦♥ and t♦♣❉❡❝♦r❛t♦r are exactly the same pointcuts as for solution B, except that these are not used as notification pointcuts. The real notification pointcut follows: ❞❡❝♦r❛t♦r◆♦t✐❢② targets the action in the control flow of ❉❡❝♦r❛t♦r❋✐❣✉r❡, but retrieves the responsible figure from the t♦♣❉❡❝♦r❛t♦r pointcut.

♣♦✐♥t❝✉t ❞❡❝♦r❛t♦r❆❝t✐♦♥✭✮✿ ❡①❡❝✉t✐♦♥✭✈♦✐❞ ❉❡❝♦r❛t♦r❋✐❣✉r❡✳s❡t❆ttr✐❜✉t❡✭✳✳✮✮❀ ♣♦✐♥t❝✉t t♦♣❉❡❝♦r❛t♦r✭❉❡❝♦r❛t♦r❋✐❣✉r❡ ❞❢✮✿ t❤✐s✭❞❢✮ ✫✫ ❞❡❝♦r❛t♦r❆❝t✐♦♥✭✮ ✫✫ ✦❝❢•♦✇❜❡•♦✇✭❞❡❝♦r❛t♦r❆❝t✐♦♥✭✮✮❀ ♣♦✐♥t❝✉t ❞❡❝♦r❛t♦r◆♦t✐❢②✭❋✐❣✉r❡ ❢✮✿ ❡①❡❝✉t✐♦♥✭✈♦✐❞ ❋✐❣✉r❡✰✳s❡t❆ttr✐❜✉t❡✭✳✳✮✮ ✫✫ ❝❢•♦✇❜❡•♦✇✭t♦♣❉❡❝♦r❛t♦r✭❢✮✮❀
A general benefit from the use of a specific control flow language is that 1) it is easier and safer than using, if possible, stack inspection; 2) it allows to easily discriminate for each method between A, B or C strategies. In a traditional object-oriented solution, the cost of implementing such mechanisms across many classes for each action is too high: usually one strategy is implemented and all actions stick to it. [START_REF] Denier | Understanding Design Patterns Density with Aspects[END_REF] shows how C notifications are implemented using a CHAIN OF RESPON-SIBILITY pattern. 4.2.3. ❖❜s❡r✈❡r, ❉❡❝♦r❛t♦r and ❈♦♠♣♦s✐t❡ as Aspects

We now examine whether the notification strategies for the OBSERVER pattern can be implemented in the presence of the aspectized DECORATOR (Section 3.2, especially dynamic as in Figure 5) and COMPOSITE (Section 4.1) patterns. The property to remember is that strategies B & C imply a recursive structure and recursive behaviors.

The aspectual COMPOSITE pattern provides these structure and behaviors. We simply need to adapt the pointcut syntax to the programming style for actions. Indeed, actions can be implemented using either for-loop or r❡❝✉rs❡❆•• with an aspectual ❱✐s✐t♦r. The later case asks for a redefinition of pointcut. The ❛❝t✐♦♥ pointcut now targets the r❡❝✉rs❡❆•• method from the ❈♦♠♣♦s✐t❡Pr♦t♦❝♦• aspect. The figure retrieved and the precise action targeted are now arguments of this method: in particular, the visitor type (▼♦✈❡❱✐s✐t♦r) is used to discriminate the action.

♣♦✐♥t❝✉t ❛❝t✐♦♥✭✮✿ ❡①❡❝✉t✐♦♥✭✈♦✐❞ ❈♦♠♣♦s✐t❡Pr♦t♦❝♦•✳r❡❝✉rs❡❆••✭✳✳✮✮❀ ♣♦✐♥t❝✉t t♦♣▲❡✈❡•◆♦t✐❢②✭❋✐❣✉r❡ ❢✮✿ ❛r❣s✭❢✱▼♦✈❡❱✐s✐t♦r✮ ✫✫ ❛❝t✐♦♥✭✮ ✫✫ ✦❝❢•♦✇❜❡•♦✇✭❛❝t✐♦♥✭✮✮❀
As underlined in Section 3.2, the aspectual DECORATOR pattern does not allow recursive composition. In fact, it works not by a recursive relation but by crosscutting each instance of target classes. Our pointcuts for strategies B & C in Section 4.2.2 are useless. One solution could be for the ❖❜s❡r✈❡r to test the ❉❡❝♦r❛t♦r aspect for its current components (Figure 5, see lines 2 and 9) -this is not as refined as using ❝❢•♦✇. However, such a solution is not necessarily needed: retrieving a responsible ❋✐❣✉r❡ for notification generally implies a later call to this ❋✐❣✉r❡, for some purpose. This later call will then be advised by the oblivious ❉❡❝♦r❛t♦r, which will perform the decorated effect (or so we assume).

Analysis of Composition by Aspects

The different cases exposed above ask for an examination of their compositional form. The case of COMPOSITE and VISITOR aims at testing the composition of reusable patterns, in order to produce a reusable composition. The case is successful with respect to this objective. We attribute this to the new VISITOR pattern, which is not hampered by a static structure.

The case of OBSERVER pattern with COMPOSITE and DECORATOR patterns is more puzzling: the use of AspectJ allows more expressiveness at a low cost, although it clearly depends on the implementation of the structural patterns. Whenever some solutions use a structure of objects, we see an impact on the pointcuts of the OB-SERVER pattern. This is the case for both the ❈♦♠♣♦s✐t❡ object and aspect, as well as for the ❉❡❝♦r❛t♦r object. However, handling an instance with the ❉❡❝♦r❛t♦r aspect seems problematic: OBSERVER pattern pointcuts need no modification but we assume that the obliviousness nature of ❉❡❝♦r❛t♦r will solve the case. This shows there is some heterogeneity in the way we can handle object instances and aspect instances. Overall, we notice that only the customization (by pointcut) of the OBSERVER pattern needs changes. Both COMPOSITE and DECORATOR patterns are unchanged.

Related Work

Many approaches have been tried -and debated [START_REF] Chambers | A debate on language and tool support for design patterns[END_REF] -to ease design patterns use. These include tools and models to generate (Albin-Amiot, 2003), detect [START_REF] Guéhéneuc | Un cadre pour la traçabilité des motifs de conception[END_REF], and refactor design patterns in object-oriented languages. Language approach is different, as languages do not directly target design patterns, but rather revisit pattern solutions with their mechanims. In this section we focus on work related to languages and aspects.

Implementation of Design Patterns in Object Languages

Several attempts to express design patterns at language level have been proposed. For example [START_REF] Tatsubori | Programming support of design patterns with compile-time reflection[END_REF] use the OpenJava MOP to reify some design patterns in Java source code. We expect a more declarative way to proceed by using an aspect language such as AspectJ. In [START_REF] Bosch | Language support for design patterns[END_REF] author use a language which facilitates the expression of inter-class relationships. As design patterns can be seen as collaborating objects, this kind of languages helps efficiently in the implementation of some design patterns. Aspect languages promise a more general approach and also better mechanisms to modularize (and maybe reuse) design patterns implementation.

Expression of Design Patterns in Aspects Languages

The OBSERVER pattern is often used to present and evaluate new features of aspect languages. Caesar [START_REF] Mezini | Conquering Aspects With Caesar[END_REF] comes with an instantiation model which seems to circumvent the role idioms of AspectJ. Reflex [START_REF] Tanter | Partial Behavioral Reflection: Spatial and Temporal Selection of Reification[END_REF] can arbitrarily define and link metaobjects to hooksets, contrary to the constrained AspectJ model.

The Demeter language -DJ for its variant in Java [START_REF] Lieberherr | Aspect-Oriented Programming with Adaptive Methods[END_REF] -has long been know to embody the VISITOR pattern. It focus on object structures whereas AspectJ focus more on control flow. Recently, [START_REF] Lieberherr | Expressiveness and Complexity of Crosscut Languages[END_REF] shows similarities between DJ and AspectJ with regards to the relational aspect of their pointcut languages. We believe that our experiments in AspectJ, such as COMPOSITE and VI-SITOR (Section 4.1), or COMPOSITE and OBSERVER using control flow (Section 4.2), provide an illustration of how dynamic structures are related to static structures and how to exploit them.

Few work has studied other patterns. One interesting case is MEMENTO, for which different attempts with AspectJ have been made [START_REF] Marin | Refactoring JHotDraw's Undo concern to AspectJ[END_REF]. To date the sole extensive study of single design patterns implementation with aspects is in [START_REF] Hannemann | Design pattern implementation in Java and AspectJ[END_REF]. However, none of the work above has studied the composition of design patterns.

Engineering Properties in Aspect Programming

Work such as [START_REF] Walker | Composition Patterns: An Approach to Designing Reusable Aspects[END_REF][START_REF] Lieberherr | Aspectual Collaborations: Combining Modules and Aspects[END_REF] deals with modularity and reusability of aspects: they often rely on design patterns (such as OBSERVER) in their examples. This suggest reusable design patterns libraries with aspects. Evolutivity is also a problem for aspects as well as for design patterns. Many pieces of work have focused in particular on robustness of pointcuts [START_REF] Gybels | Arranging Language Features for Pattern-based Crosscuts[END_REF][START_REF] Aldrich | Open Modules: Modular Reasoning in Aspect-Oriented Programming[END_REF][START_REF] Ostermann | Expressive Pointcuts for Increased Modularity[END_REF]. [START_REF] Kniesel | Generic Aspect Languages -Needs, Options and Challenges[END_REF] argues that generic metaprogramming for aspects is more useful for some design patterns, such as DECORATOR and VISITOR, than reusability of aspects. Kniesel et al also advocates that the systematic use of interfaces as roles in AspectJ hamper genericity. We support this claim for the VISITOR pattern, but we present a rewriting of this pattern which is more generic while not relying on the powerful tools of metaprogramming.

Conclusion

This articles provides an overview of AspectJ idioms commonly used to implement design patterns. We show an extension of the AspectJ DECORATOR pattern, enabling dynamic attachment to objects. We highlight a more generic and reusable VISITOR pattern, which allows multiple dispatch and thus improves on the classic object-based visitor. Our visitor also works with the COMPOSITE pattern in a reusable composition. The OBSERVER pattern gains expressiveness in face of tree structure built by COMPOSITE and DECORATOR patterns.

Basically, aspects provide better modularization of design patterns, improving traceability and dependency control. Our primary results show that such modularization can be beneficial for the composition of design patterns. Interactions can be localized into aspects, such as for the OBSERVER pattern with COMPOSITE and DE-CORATOR patterns, and reusable compositions can be defined.

Language mechanisms which come with aspects, although not specific, also improve solutions. For example, we use dynamic type predicates to enable a better VI-SITOR pattern, and ❝❢•♦✇ constructs to give expressive semantics on tree structure crosscutting. Aspects still provide modularization for these powerful expressions, which help to cope with complexity of implementation. Finally, we notice that aspects have a large scale of grain for adaptation: an aspect can be expressive relative to a whole object structure (such as a tree) as well as to a single method in a class. However, many of our examples were impacted by the instantiation model of AspectJ: the DECORATOR pattern do not allow recursive composition and is oblivious to the OBSERVER pattern; the VISITOR pattern requires a class to scope the aspect. Many design patterns implementations from [START_REF] Hannemann | Design pattern implementation in Java and AspectJ[END_REF] rely on idioms to implement relationships between objects. We understand this as a sign of the heterogeneous nature of AspectJ, which does not allow to control aspect instances as class instances. These shortcomings obviously result from the AspectJ language design -aiming at simplification and robustness -and as such seem specific to AspectJ, not to aspects in general. Nevertheless, we consider these shortcomings to highlight an important characteristic of aspects languages: how do they define aspect instantiation and scope (during execution)? One should be careful when choosing an aspect language, as this likely constraints aspect control, impact and definition.

Another guideline is that aspect languages do not support all design patterns. We do not expect aspect languages to perform as large as metaprogramming, for example, when it comes to statically upgrade a class (although AspectJ ITDs allow some modifications).

In [START_REF] Denier | Understanding Design Patterns Density with Aspects[END_REF], we have started to study composition of design patterns through pattern density and framework development. To generalize composition, we need some formalization or at least some classification. Then we can proceed with an evaluation (of the frequency) of such compositions on the current set of design patterns. Eventually, we expect a catalog of common composition.

The instantiation shortcomings and the use of idioms should not hide opportunities for new solutions triggered by language mechanisms, such as for the VISITOR pattern. We expect patterns concerned with dynamic adaptation to be especially sensitive: this includes STRATEGY, COMMAND, or CHAIN OF RESPONSIBILITY patterns.

It could be interesting to look for a partial automation of aspect composition. For example, the registration process of the OBSERVER pattern can be coupled with that of the COMPOSITE pattern once composed. Tools for detection of aspect interactions can be used in this process.

Figure 1 .

 1 Figure 1. Two options among others of the AspectJ instantiation (and scope) model. a) is the singleton model, where an aspect defines a unique instance, which can crosscut any objects. b) is the per-object model, where an aspect defines one instance per crosscutted object: the aspect instance can only crosscut its object

1Figure 2 .Figure 3 .

 23 Figure 2. An abstract, reusable version of the OBSERVER pattern with AspectJ. We use inter-type declarations to implement the structure in the ❙✉❜•❡❝t interface. Notice how the registration is also defined as an advice

Figure 4 .

 4 Figure 4. Basic DECORATOR pattern, adapted from Hannemann

  Figure 5. New DECORATOR pattern with dynamic application possibility Still, this solution lacks two properties of the object-based DECORATOR pattern:

1Figure 6 .

 6 Figure 6. The new abstract pattern for VISITOR

Figure 7 .

 7 Figure 7. Customization of the VISITOR pattern for a particular structure (see also Section 4.1.2)

Figure 8 .

 8 Figure 8. The abstract, reusable version of COMPOSITE; a noteworthy feature is the integrated VISITOR pattern

Figure 9 .

 9 Figure 9. Customization and use of COMPOSITE-VISITOR

Figure 10 .

 10 FigureFigureFigure

a

  tree with COMPOSITE and DECORATOR patterns. An action launched on any figures is recursively dispatched to its children

Acknowledgements

The authors would like to thank the anonymous reviewers for their comments as well as Mikal Ziane, whose remarks help to further improve this article.