New Perspective To Improve Reusability in Object-Oriented Languages
Philippe Lahire and Laurent Quintian, I3S Laboratory,
University of Nice-Sophia
Antipolis and CNRS, France |
 |
REFEREED
ARTICLE

PDF Version |
Abstract
Object-oriented languages provide insufficient answers regarding reuse
of hierarchies
of classes especially because mechanisms provided for separating application
concerns
are not sufficient. We propose to extend object-oriented languages,
Java in the current
implementation, to address this particular issue. The model, inspired
by approaches
dedicated to the separation of concerns, introduces a new concept called
adapter. It
enables to specify the composition protocol of a hierarchy of classes
independently
from the context of use. This composition protocol allows the programmer
to benefit
from the necessary guidance and controls when the adapter is customized
to be
integrated into applications.
1 INTRODUCTION
The reuse of the code written for one application to develop
new ones is essential to
be able to react quickly to the market needs but most of the time it
is necessary to
adapt the existing code in order to reuse it. Reusability represents
one of the most
important challenges of object-oriented languages [13] but we have
to admit that,
whatever the skills of existing programming languages are, this objective
is far from
being reached, in particular because the adaptation mechanisms (based
on feature
renaming or redefinition) are not powerful enough.
One of the keys of software reusability is to separate the various
concerns of
a software and to make them as much independent as possible from the
future
contexts of use. Depending on the nature of the concern which is addressed,
it may
be represented by a set of features (attribute or method), a set of
statements, one
class or a set of classes, one or several hierarchies of classes, etc.
From a general
point of view, a concern represents one facet of the problematic addressed
by an
application.
A concern is known as functional, non-functional or hybrid. Let us
give some
more explanation about this classification of concerns.
Generally an application is composed of several facets like:
- the extraction or storage of application data,
- the control of data consistency,
- the evaluation or computation of data,
- their display through the use of either a textual or graphical
interface.
Each of these facets corresponds to a set of functionnalities which
implements
the associated objective. Such a piece of software is called a functional
concern. For
example, libraries of classes provided by object-oriented languages
and dedicated to
one purpose may correspond to a concern.
When applications need to extend existing functionnalities with additional
processing
(often called services), like persistence handling, distribution
of data, support
of various forms of security or method-call tracing [10], then
it is a non-functional
concern. In Section 2 we will address a hybrid concern which extend
existing functionnalities
but also add new ones.
When a concern is identified and described, whether functional
or non-functional,
an important issue is to get a sufficient expressiveness to recompose
those concerns
so that applications may be specified. Two different situations
may occur: the
contents of the concern may be located in a single location (for
example within a
class or a hierarchy of classes) or it has to be spread out into
the system of classes.
If we focus on highly flexible applications, which are more and
more numerous
with the development of ubiquitous computing, we observe that
the means provided
by the object-oriented languages are insufficient. The main
reason is that to implement
separation and composition of hierarchies of classes, object-oriented
languages
mainly rely on various concepts of class, possibly generic,
and on both inheritance and aggregation relationships. But the experiments that may
be found in the litterature
show that it leads to costly feature redefinitions and to a
large duplication
of code. In some situations object-oriented languages do not
even offer any realistic
solution for the composition of concerns. This is typically
the case when a concern
is spread out into the application or when the number of concerns
to be composed
evolves constantly and makes the resulting hierarchy too complex
very quickly.
Following these observations other paradigms emerged to address
the needs of
modern applications. Among others we may mention the separation
of concerns
[12], programming by components [21] or programming by models
[5]. We think
that object-oriented languages should accept the challenge
and provide mechanisms
supporting, in some form, the separation of concerns. These
mechanisms should
fit nicely with object-oriented concepts, in particular reuse,
and applications using
those facilities should be as robust and reliable as applications
built upon pure
object-oriented mechanisms. To go in this direction, we propose
a generic approach
(independent of existing object-oriented languages), to extend
the object-oriented
languages with a set of adaptation operators applying on
classifier diagrams1.
This approach respects the following hypotheses: i) describing
and separating
the various concerns relying strongly on the object-oriented
language which is chosen
to program the application, ii) enabling the specification
of a composition protocol which is documented and comprehensive enough
to guide and control the reuse of
each reusable concern.
Our model is inspired by the existing approaches dedicated to the
separation of
concerns (ASoC - Advanced Separation of Concerns). Approaches for
the separation
of concerns include aspect-oriented programming (AOP) [12], subject-oriented
programming
(SOP) [17], role or point-of-view oriented programming [9], composition
filters [1] or, to a lower extent, mixins [2] and metaprogramming
[4]. The state of
the art and the detailed study proposed in [20] show that the languages
offering the
most interesting expressiveness are AspectJ [11, 10] (AOP) and
Hyper/J [18] (SOP).
Section 2 presents our choices for the description of concerns
and sets the bases
of an example which is particularly representative and on which
the remaining parts
of this document rely. Section 3 provides an overview of both
the composition
model and the type of adaptations supported in our approach.
Section 4 relies
on the previous sections to describe how to equip a concern in
order to improve its
reusability. Section 5 provides some more details about the semantics
of adaptations.
Section 6 gives an overview of the implementation and addresses
the state of the
art. In particular it compares the contribution of our approach
to AOP and SOP.
The last section draws conclusions and describes some future
works.
2 DESCRIBING APPLICATION CONCERNS
A concern is made up of classifiers (class, interface. . . )
or hierarchies of classifiers
and it is reasonnable to assume that it is encapsulated in
one container (a package for example) which may possibly contains itself other sub
containers.
In the following example we use the Java syntax in order
to define the two
concerns that we consider but the composition model relies
on a reification of objectoriented
languages and not on a given syntax.
We now suggest to consider two possible concerns of an
application: the graphical
user interface (from now referred to as GUI) and the
design pattern Observer
[7]. In this section we describe each of these concerns
independently from each
other. Section 4 benefits from the information given
in Section 3 about both the
supported adaptations and the modelling of the composition
protocol. It explains
how to specify the composition protocol of the concern
Observer and shows how to
implement and control its integration within the concern
GUI.
Concern Design Pattern Observer
The design pattern involves the classifiers Observer,
Observable and ImplObservable2
(see Figure 1); they are independent from any application.
The reader
may notice in particular that the concern is encapsulated
within the Java package designpattern.observer. The
interfaces Observer and Observable correspond to the two roles of
the pattern. The class ImplObservable is a staightforward
implementation of the interface Observable. It relies on the classes ArrayList,
List and Iterator which are defined in the packages of the Java library (java.util).

Figure 1: Design pattern Observer
At this stage, the developer may only notice that i) any class implementing
the interface Observer must specify a body for the method updateObserver and
ii) both interfaces are strongly coupled because each of them requires
the other in
the signature of their methods. To easily reuse this concern, and
more generally
all concerns, it is mandatory to add a more comprehensive documentation:
the
composition protocol which will be addressed in Section 4.
Concern Graphic User Interface
The concern in which we want to integrate the design pattern Observer deals with
the implementation of GUI applications. It is obvious that the
proposed GUI is
very basic and fully dedicated to the example. But it is simple
to understand and
complex enough to explain our approach and to show its contribution.
The GUI concern is encapsulated in the Java package application.ihm (Figure
2). It describes two types of graphical objects: buttons (class
Button) and labels
(class Label). These two classes are based
on classes from the Java swing library,
JButton and JLabel.
The redefinition of the method fireActionPerformed within
the class Button is not mandatory. Its only interest is to make
the example more
understandable.

Figure 2: Description of the GUI concern
The class ApplicationInterface contains the GUI initialisation
and an entry
point to launch the application. Figure 2 shows the full source
code, but only the
initialisation of the objects referenced through button1, and
label1 in the class
constructor (lines 24 to 35 ) will be used in Section 4 for the
explanation dedicated
to the composition of the two concerns.
3 MODELLING THE COMPOSITION OF CONCERNS
Before going further in the description of the example, it is
necessary to address the
composition model and the adaptations which may be applied
to the concerns to
weave them one another.
Composition Model
The adaptations which are involved in the implementation of the concern
composition
rely on concepts that belong to most languages and on one or several
transformation
or typing rules; thus it is reasonable to propose a common reification
for the
entire set of properties (of course it is possible to extend the
reification at any time
without breaking the model architecture). As we mentioned it earlier,
a concern is
encapsulated in one hierarchy of containers (package, cluster .
. . )3 which contains
classifiers. A classifier (class, abstract class, deferred class,
interface. . . ) may inherit
from one or several other classifiers. A classifier belongs to a
container and it has
modifiers (abstract, deferred, final, frozen, public. . . ). It contains
attributes (constants,
instance or class variables), methods (procedure, function or constructor)
which need or not the creation of class instances. The methods have
a signature
(name, parameters, return type. . . ), modifiers and a body which
corresponds to a
set of statements. Most of the time it is not useful to consider
the semantics associated
with the language reification. We have to consider it only when this
semantics
influences the description of an adaptation.
An adaptation is located in one or several adapters, that is to say,
outside the
class to adapt; these adaptations are non intrusive. Figure 3 presents
the main
entities that enable to describe concern composition and thus the
building up of
an application. This composition is represented by one or several
adapters. At
the present time the mechanisms dedicated to the composition of
adapters are very
limitated and only guarantee that adapters which may create new
concerns are
handled first (further they are called ex situ adapters).
Each adapter has a unique name that allows to identify it. It may
be concrete
or abstract and it may inherit from another adapter. This inheritance
mechanism
is basic and allows only two of the usages of inheritance defined
by B. Meyer [13] : reification inheritance and functional
variation inheritance.
An adapter contains
adaptation targets that are concrete or abstract4 depending on
whether the entities
on which the adaptation applies are fully specified by the declaration
or not. An
adaptation target is typed and deals with either a classifier,
a method or an attribute.
When an abstract adaptation target is declared, it is possible
to set some
constraints to be satisfied. A concrete adaptation target contains
either an explicit
list of identifiers (depending on its type, names of classifier,
method or attribute),
or a regular expression whose evaluation will generate the list
of identifiers; its expressiveness
is quite similar to the regular expressions of AspectJ [10].
An adapter
also contains adaptation operators typed with the adaptation
target. If the adapter
is defined ex situ, then a new container (one package in current
implementation) is
created and the concerns related to the adaptation are inserted
into it. If it is in
situ, then the container already exists and the result of the
adaptation modifies the
concern associated with it.

Figure 3: Reification of concern composition
Supported Types of Adaptations
Our model supports five categories of adaptation and each of them
addresses several
types of adaptation. This list can be extended in the future if new
capabilities are
found useful. Figure 4 shows that the design choices applied to the
model enable
to increase at any time the list of adaptations without questioning
the model or
the implementation architecture. The five categories of adaptation
are presented in
table 1. In particular it indicates if an adaptation introduces a new
functionality
(functional adaptation) or if it extends the description of existing
functionalities in
order to associate them with some new services (non-functional adaptation).
The adaptations supported by our model fit into this classification
as follows
(the order is the same as in table 1):
- implementation of new interfaces or insertion of a new
super-class (SuperClassifierIntroduction);
- fusion of methods (MethodMerging) with several
variants enabling to specify
that the body of the first method is located before (MergingBefore),
after
(MergingAfter) or if one of the method is abstract (MergingWithAbstract),
and fusion of classes (ClassMerging) with the ability,
either to only add methods
or attributes (FeaturesOnlyadded), or to merge the body
of the methods (CustomizedMerging);
- insertion (MethodIntroduction) or redefinition
of methods (MethodRedefinition);
- insertion of new instance or class variables into classes
(AttributIntroduction);

Table 1: Adaptation categories suitable for the reuse
of concerns
- interception before (BeforeInterception),
after (AfterInterception), around (AroundInterception)or when an exception
is triggered on methods (OnExceptionInterception),
whatever they apply to (instance or class);
- interception of the accesses to the instance or class variables
OnGet/OnSet). In
this case we also enable the integration of treatments before or
after retrieving
the information (BeforeGet and AfterGet) or before
and after updating the
variable (BeforeSet and AfterSet).
Each type of adaptation contains two methods: the first one is check,
it controls
that the constraints required by the execution are satisfied; the second
one is execute,
it describes the behaviour of the adaptation.
Section 4 will give a preview of some of the adaptations supported
by our model
through the continuation of the examples started in Section 2. Section
5 will give
more details about the semantics of adaptations.
4 EQUIPPING A CONCERN TO BE REUSED
As a summary of what was written in the previous sections, we claim
that the
implementation of the approach must rely on these two key-ideas:
- Integration of concerns into the programming language used.
A first experimentation
uses the Java language but the previous sections show that the
approach is not dedicated to a particular language.
- Having a set of adaptation operators which is expressive
enough to enable the
composition of functional and non-functional concerns.

Figure 4: Reification of the adaptations which are
supported In this section we aim to demonstrate
that reusability means to propose an
approach for the composition of concerns which relies on the following
fundamental
principles:
- Being able to delay the specification of the entities
on which the adaptation
applies, whatever the adaptation operator is.
- Encapsulating the definition of the composition protocol
(or pattern) which is
dedicated to a given concern in order to make it independent from
the context
of the future uses.
- Making the composition protocol expressive enough to guide
and control the
reuse of the concern.
- Enabling the concretisation of a composition pattern to
adapt it to the context
of use.
- Providing two kinds of composition: if we consider two
concerns to be composed,
the type in situ composes one of the concern into the
other one while the type ex situ creates a new concern
which contains the composition of the
two. The second kind of composition is particularly suitable when
a concern
must be composed several times in various locations of the application.
Forthcoming subsections constitute a direct continuation of the examples
started
in Section 2. We use the hierarchy of adaptations described in Section
3 in order
to describe successively the composition protocol of the concern
Observer and a
specialization of it to take into account specificities of the concern
GUI.
We decided to make only one concern reusable (the pattern Observer);
the
concern GUI is described for the specific needs of the example. This
is why this
paper only describes one composition protocol. But if work is done
in order to make
the GUI concern reusable, then it would be interesting to define a
composition
protocol for it.
Composition Protocol of the Concern Observer
As mentioned earlier, the composition protocol of the design pattern
Observer (Figure
5) has two main objectives:
- describing the methodology associated with the use of the
concern to assist
the programmer during the reuse process,
- providing the necessary material to control that the programmer
applies the
given methodology when he adapts the composition protocol to a
specific context (for example the one of the concern GUI).
The syntax proposed hereafter5 is essential because it corresponds
to what is
given to the programmer of the design pattern Observer to specify
its methodology
of reuse. However, it is only a particular view of the model of which
Sections 2 and
3 gave an overview. Still, we initially wanted to make the syntax
as close as possible
to the Java language in order to consider the entity adapter as a
special kind of
classifier [20]. But the specificity of its contents led us to prefer
an ad hoc syntax
guaranteeing a better readability and making it possible to consider
the extension
as a language dedicated to the adaptation of classes (Domain Specific
Language).
Only the pieces of code describing the behaviour to be inserted or
modified are
written with the application programming language. Currently we are
thinking of
some syntax refinement to better isolate the corresponding statements.
While examining the contents of Figure 5 we notice that it is independent
from
its future contexts of use. The line 01 indicates the concern
to which the composition
protocol (the design pattern Observer) is attached. The entity
describing
a composition protocol (ligne 02 ) is an adapter (keyword adapter)
and has a
name (here ObserverAdapter). The keyword abstract appears before
the keyword
adapter because the adapter contains some abstract adaptations.
Adaptations are
introduced by the keyword adaptation. Each of them has a name and
relies on
entities (class, method, attribute), which represent the adaptation
targets (keyword
target). The keyword abstract precedes each abstract adaptation
or abstract
adaptation target and it is mandatory to specify a comment. We
consider that the
documentation of an adapter is crucial because it improves the
reusability of concerns.
The description of the composition protocol proposed hereafter
is made up
with three parts: i) the observable entities, ii) the entities
which observe and, iii)
the concern which uses the design pattern.

Figure 5: Composition Protocol of the Pattern Observer The
lines 04 to 13 describe the targets and adaptations related to the
observable
entities. The adaptation targets observableClass and notifyingMethod respectively
deal with the observed instances and the methods that must notify the
entities
observing them. At the time the composition protocol is specified,
these methods
and classes are not known yet, this is why the targets are preceded
by abstract.
They will become concrete when the programmer who wants to use the
design
pattern composes it with the chosen concern (GUI in our example). Nevertheless
because it is possible to specify abstract adaptation targets, it is
already possible to
describe the corresponding adaptations. Two adaptations were specified:
one of type
FeaturesOnlyAdded (keyword extend class) and another of type AfterInterception
(keyword extend method).
The first adaptation indicates that the contents of class ImplObservable must
be inserted into the classes whose instances are observed. For the
languages with
multiple inheritance, such adaptation could be replaced by an adaptation
of type
SuperClassIntroduction. The second adaptation describes the insertion
of a call of
the method identified by notifyObservers at the end of the methods
referred to by
notifyingMethod. These methods must belong (keyword require) to the
observed
classes (observableClass). The call to the method notifyObservers enables the
instances of the classes to play the role of observers to be warned
of some state
changes and to trigger the execution of a set of statements.
The lines 14 to 20 describe the adaptation target and two adaptations
dealing
with classes whose instances observe those addressed by the lines
4 to 13. The adaptation
target observerClass refers to the classes chosen for playing this
role. These
two adaptations are of type SuperClassIntroduction (keyword inherit)
and of type
MethodIntroduction (keyword introduce method). The first adaptation
adds the
interface Observer to the classes attached to the adaptation target
observerClass6.
Let us mention that the interface Observer contains a method update
which is of
course abstract so that the second adaptation is abstract too.
This indicates that an
implementation must be attached when the context of use is known.
It corresponds
to the action to be performed on the observing instances.
The lines 21 to 37 describe the initialisation required to introduce
the design
pattern into the user concern. This initialisation fills the
contents of the collection of
instances which observe. It is located in the observed instances.
The collection corresponds
to the attribute observers and insertion of instances is done
through method
addObserver, both of them defined in the class ImplObservable.
Four adaptation
targets are specified to implement this initialization: i) applicationInitClass and applicationInitMethod correspond to the classes and methods
where the attachment
between the observed instances and the ones which observe is
set, ii)
observableInstance points out to the attributes referring to
the observed instances
and, iii) observerInstance records the attributes referring to
the instances which
observe. The insertion of the attachment is done through an adaptation
of type
AfterInterception (keyword extend method).
We may also note that the composition protocol described in Figure
5 permits to
ensure that the attributes pointed out by observableInstance and observerInstance are declared within the method which correspond to applicationInitMethod
(keyword require). The same approach is used (lines 06 to 12 ) to ensure
that
the methods pointed out by the adaptation target notifyingMethod belong
to the
observed classes.
GUI-specific Adaptation
Let us now compose the concern related to the design pattern with
the concern
GUI. This task, which is assigned to the programmer of the application,
is specified
within a concrete adapter (Figure 6). Its contents seems a priori very simple but
we show that inheritance of the abstract adapter (Figure 5) allows
to control that
the content is consistent with the composition protocol. The reader
may also notice
that the abstract adapter contains enough information to produce
a comprehensive
skeleton of the concrete adapter.
Lines 01 and 02 indicate that the concern Observer is composed
(keyword
compose) with the concern GUI. Because the package of the adapter
(package
application.IHM) is the same as the one of the concern GUI, the
composition is
then in situ. The adaptations will be performed directly within
the classes Button,
Label and ApplicationInterface which are in this package. Choosing
a composition ex situ would produce the result of the composition in another
container. It
would also facilitate a new composition of the design pattern
Observer with, for
example, a transparent handling of the storage of the modified
objects.
The adapter ApplicationIHM makes the adapter ObserverAdapter concrete.
Its role is to complete its declarations. It is the adaptation
name or the adaptation
target that enable to bind the adapter with its homonym in
the abstract adapter.
The major part of these declarations is made with abstract
adaptation targets (lines
04 to 10 ). It is worth mentionning that if one of
the adaptation targets is missing
ApplicationIHM, this will be detected, because it is not possible
to define a concrete
adapter if some of its caracteristics remain abstract7.
The concretization of the abstract adaptation targets implicitly
completes the
declaration of the corresponding adaptations. One may notice
that some of the adaptation
targets are concretized by an explicit enumeration of identifiers
(observableClass, ObserverClass, notifyingMethod or applicationInitMethod),
whereas
others are concretized by a regular expression (observableInstance and observerInstance). Note that the concretization of an
adaptation target may rely on another
one declared within the adapter itself or in one of its parents
(lines 08 to 10 ). To
make the description of adaptation targets easier we should
not restrict ourselves to 
Figure 6: Concretization of the composition protocol for the GUI classical
regular expressions8 but we should extend their expressiveness
to be able
to point out, without enumerating them, the whole set of
leaves of a hierarchy or
all ancestors of a class. At the end, ApplicationIHM contains
the description of the
body of method update which should handle the specific
needs of the concern GUI9.
If you forget to concretize this method, it will be detected
when the composition is
performed.
To better differentiate the adapter and the behaviour
attached to the concern, it
may be interesting to isolate the pieces of code representing
this behaviour (which
is currently specified within the adapter; see line 12 of Figure 5 and lines 12 to 15 of Figure 6), into a specific class and to refer to it
within the adapter.
5 MORE ON THE SEMANTICS OF ADAPTATIONS
This section adds more details about the description
of the set of adaptations supported
by our approach. When it is suitable it refers to
the example of composition
of concerns presented in Section 4.
Providing the full reification of the adaptations
would take too much space without
bringing so much significant information. Therefore,
we only mention the reification details and the
controls influencing the understanding of the model10.
There are eight variants of adaptation of type
Interception. They apply at different
steps of a method execution or of an attribute
access. They are strongly
influenced by AspectJ [11, 10]. They deal with
attributes and method bodies. In
the context of Java, these adaptations are performed
more on classes than on interfaces
because the latter may not contain method bodies
and the attributes are only
class constants (defined as static final).
Four adaptations deal with methods. The adaptation AroundInterception enables
executing a piece of code attached to the adaptation. Very
often this code
contains one condition if-then-else with, in one of the
parts then or else, the keyword
proceed, which means to perform the
original code of the method. This type
of interception enables choosing whether the method must
be performed according
to the context of execution.
The adaptation BeforeInterception (respectively AfterInterception)
enables executing
a piece of code before the first statement (respectively
after the last statement,
when it ends normally) of the original code of the method.
If an exception is triggered
and we need to modify the corresponding behaviour, then
the adaptation OnExceptionInterception must be used to specify the additional statements that
should be
performed if an exception is triggered. Adaptations of
type AfterInterception are
showed in Figure 5 lines 10 to 12 and lines 33 to 36.
Four other adaptations apply to attributes (whether they
are shared by all occurrences
of a class or belong to only one given occurence). These
adaptations enable to
specify a piece of code when the value of an attribute
is read OnGetInterception or
modified OnSetInterception. The execution of this piece
of code is triggered either
before this operation (BeforeGet or BeforeSet), or after
(AfterGet or AfterSet).
There is another type of adaptation related to the body
of a method: the MethodRedefinition.
It allows the method body to be modified freely. Its counterpart
for
attributes also exists for programming languages supporting
this feature (for example
Eiffel).
The fusion of a class A with a class B is implemented
by adaptations of type
ClassMerging. They are inspired by facilities provided
by Hyper/J [18]. Their
semantics is the following: i) The super-classes of class
A are inserted in the list of
super-classes of class B. Of course, when the language
supports single inheritance
only, it is not possible to add any super-class if the
class already has one (which
is not inherited implicitly like Object in Java). ii) If
people want that the fusion
corresponds only to insertion of additional methods (with
handling of possible name
conflicts), they should use the adaptation FeaturesOnlyAdded,
otherwise there is
CustomizedMerging. For each method of class A, if one method
with the same
signature already exists in class B, then an adaptation
of type MethodMerging is
performed on the two methods (at present time, there are
three kinds of method
fusion and it is possible to choose the kind of fusion
to be applied), otherwise the
method is added to class B (adaptation of type MethodIntroduction).
iii) Each
attribute of class A, which does not already exist within
B, is copied into it. An
adaptation of type FeaturesOnlyAdded is proposed in the
lines 08 and 09 of Figure
5.
The types of adaptation implementing the fusion of one
method M with a method
M’ are a specialisation of MethodMerging. They have
the following semantics:
- When both methods are abstract, the result
of the fusion is also abstract.
- If only
one of the two methods is concrete (adaptation MergingWithAbstract),
then its body becomes the result of the fusion.
- If both methods are concrete then it is necessary
to choose whether the body of method M must
be performed before the one of method M’ (adaptation
MergingBefore) or after (adaptation MergingAfter).
From our point of view, the facilities provided by these
last two adaptations are
not sufficient and in most situations the code will have
to be inserted somewhere
else or conditionally. To cope with that, a first solution
is to use an adaptation of
type MethodRedefinition but it implies a duplication
of code. Another possibility
is to introduce a new type of adaptation that enables
to make a fusion under some
condition like in an adaptation of type AroundInterception.
In addition to the adaptations dedicated to the fusion,
interception or redefinition,
we propose adaptations enabling the insertion of super-classes,
methods and
attributes. The adaptation MethodIntroduction enables
adding a new method to a
classifier11 when it does not already exist in the
classifier, otherwise this is a redefinition MethodRedefinition).
An example of this adaptation is proposed in Figure 5
(lines 18 and 19 ).
The adaptation AttributeIntroduction allows to add
an attribute to a class if it
does not already exist in the classifier.
The adaptation SuperClassIntroduction enables inserting
a classifier within the
list of super-classes. One example of this type
of adaptation is given lines 16 and
17 of Figure 5. Let us mention that for the object-oriented
languages supporting
several kinds of classifiers such as classes (abstract
or not) and interfaces, like Java,
it is necessary to adapt the semantics of this
adaptation. It is also the case when
there are fundamental differences between inheritance
mechanisms, for example,
that inheritance is multiple in Eiffel and C++
and single in Java and C#. In our
implementation for the Java language, we made the
following choices: i) This adaptation
applies to both classes and interfaces, ii) It
is forbidden to add an interface
if it already belongs to the list of direct ancestors
and, iii) A super-class may be
introduced if the class implicitly inherits from
the class Object only.
6 IMPLEMENTATION AND RELATED WORKS
In this section we first give an overview of the
implementation, then we compare
our work with AspectJ and Hyper/J. Finally
we address other interesting related
works.
Overview of the Implementation
The model presented in the previous sections was implemented
as a prototype
(JAdaptor), it allowed us to validate the example proposed
in Sections 2 and 4. The remaining part of this section gives
an overview of the prototype implementation.
A more detailed description is available in [20].
JAdaptor was implemented with Eclipse [6] as an extension
of the Java plugin
that comes with the Eclipse delivery. JAdaptor was implemented
as a precompiler
which is executed before the Java compiler. The main tasks
performed by the
precompiler are:
- the retrieval of information corresponding
to the source code and to the adapters,
contained in the abstract syntax trees12,
- checking of the information consistency, flattening
of the hierarchy of adapters
and composition of concerns,
- the generation of the source code after the
composition is achieved.
We chose to use the XML technology
and in particular
the XML-Schema [22] as pivot model for
the specification of the adapters
associated with one concern for
several reasons: i) the description of adapters becomes
independent of any language,
which facilitates reuse of the composition protocol,
ii) people may benefit from the
large set of tools dedicated to the XML technology like
the XML editor of Eclipse or
the JAXB library [15] which enables to generate Java
classes automatically from the
information contained in XML files, iii) the generation
of a view of adapters with a
dedicated and adequate syntax is straightforward (see
Figures 5 and 6). Then it is
quite easy to implement an analyser for this syntax that
produces XML files.
It is important to underline that the implementation
of this approach relies on
both Model Driven Architecture (MDA) and generative
programming. The general
nature of concepts presented in Section 2 shows that
concerns could be described
using UML (even if in our examples we used Java). The
know-how related to the
composition of concerns (Section 3) is recorded in
a model which is independent
from the language to be extended and adaptations are
handled by transformations
of the reification of the source code, using generators.
Comparison with AspectJ and Hyper/J
As mentioned in the introduction, two of the main sources
of inspiration of our
approach are aspect-oriented programming and subject-oriented
programming. We
now have to compare it with those two programming
styles and show our contribution.
Our approach does not aim to compete with the approaches
of separation of
concerns but to improve object-oriented languages. Thus
it introduces new means
to express the specification of adaptations, which are
required for a better reuse
of class hierarchies. This is why our approach may be seen
as an extension of an
OO programming language or as a domain-specific language,
which is external to
it. In other words, the techniques used come mainly from
the ASoC but the object
paradigm is dominant.
Let us now consider the expressiveness of our approach
with respect to AspectJ and Hyper/J and compare the example described in Section
4 with its implementation
in both AspectJ and Hyper/J [8, 20]. We showed above13
that it is crucial to
be able to define a composition protocol which is independent
from its future contexts
of use. But Hyper/J does not allow it and Aspect/J allows
it only partially.
For example, in the latter some adaptations such as the
insertion of new interfaces,
methods or attributes cannot be defined independently
from the context of use. It
is the same thing for the adaptation targets which refer
to classes or attributes.
We also noticed some deficiencies for the supported adaptations.
Aspect/J does
not provide any adaptation to merge classes or methods.
The adaptations provided
by Hyper/J for the interception of method are not sufficient,
therefore very few
contextual information is accessible, so that it is
not possible to get the parameters
and return value of an adapted method. Moreover Hyper/J does not provide any
adaptation for intercepting the access to an attribute.
Finally, even if our example does not put too much
emphasis on the location of
composition, Hyper/J and Aspect/J provide only one
mode of composition: ex situ for the first one, and in
situ for the second one.
We can see that Aspect/J has better results than
Hyper/J (for the criteria we
are considering). Still, AspectJ has deficiencies.
Using it for our example would
yield the following problem: i) It is not possible
to specify the insertion of interface
Observer within the composition protocol; ii) The
contents of ImplObservable must be described directly within the abstract
aspect (it may be compared to our
abstract adapter); iii) None of the adaptation
targets necessary for the implementation
of the initialisation required by the integration
of the design pattern may be
described within the composition protocol.
Other Related Works
There are other languages or approaches dealing
with AOP and SOP. Among them,
ConcernJ [3] relies on component filters in
order to implement the separation of
concern. Caesar [14] mixes AOP with component-oriented
programming in such
a way that specifications of aspects (i.e.
the interfaces) are separated from their
implementation and from their deployment. JAC
[19] is also inspired from components
but uses a reification for the specification
of an aspect and thus requires no language
extension. Jiazzi [16] allows to program by roles or by
points of view, but
the separation of concerns may be performed
only within the same class.
The fact that several approaches are influenced
by component-oriented programming
shows the interest of such an approach for
achieving a separation of concerns
and then reusability. We can mention some
of the promising features provided by
this paradigm: component substitutability
(static and dynamic), hierarchical organization
of components, separation of interface and
implementation, separation of
the functional and configuration concerns,
etc.
7 CONCLUSION AND PERSPECTIVES
The object-oriented languages at the end
of the eighties contributed to a better
reusability of the software but the needs
of applications which are greater and
greater
everyday point out their limits. This
is why we propose a model and its implementation
to improve the reusability of languages
while preserving the robustness of
application.
Our approach relies on the idea that
to make a concern reusable implies
to equip
it with its user manual. One interesting
point of our approach is that it is
not
only textual and static, it is a full
entity (the adapter). It enables
the specification
of the entities that will be adapted
(the adaptation targets) and
the adaptations themselves.
An adapter is used only at the beginning
of the compilation
process
to
weave the concerns involved in an application.
An adapter provides i) an encapsulation
entity supporting abstract (partial)
declarations, ii) typing of both adaptations and
adaptation targets, iii) an inheritance
relationship (especially reification
inheritance [13]) which implements
dynamic binding
between the adaptations and the adaptation
targets, iv) an assertion mechanism
in order to specify the dependencies
between the adaptation targets and,
v) a textual
documentation. The fact that this approach is independent
from the chosen programming language
is also important even if the description
independency of the adapters is not
strong enough from our point of view14.
But we study some alternatives like
locating
this code outside the adapter, in
a class. The model has true evolution
capabilities.
They rely on an object reification
which benefits from the underlying
language
(modularity, inheritance. . . ).
The set of concepts addressed in
Section
2 and
the
hierarchy of adaptations described
by Figure 4 are extendible. The independence
of
the approach and the evolutivity
of the model are favoured at the
implementation
level by the use of the XML technology
and by the generative capabilities
provided
by the Eclipse platform.
Perspectives of our work include
the improvement and extension of
the model,
and improvement of its implementation.
On the implementation side, it
would be interesting to consider
directly the Java byte-code in order, for example, to use
our
approach to reuse libraries provided
without their source code. It would
be also
interesting to validate our model
on other languages such as Eiffel
or C++.
We aim to perform some improvements
upon the suggested model in order
to
resolve its weaknesses and to
increase the expressiveness of
the composition
model.
First the hierarchy of adaptations
should be extended to offer new
adaptation capabilities.
In particular it is necessary
to provide the ability to modify
the
import clause of a class. The support
of this adaptation is mandatory
to be able to implement
composition ex-situ within already
existing applications and to
specify them
into the composition protocol.
The fact that generic classes
are supported by several
languages suggests proposing
adaptations dedicated to this
kind of classifier
which allow to take into account
generic parameters. Other improvements
include a
better support for composition
of adapters attached to the same
concern, and
improvement of the flexibility
of the composition protocol by
enabling to define alternative
adaptations. It is important
to be able to reuse the associated
concern in
an even greater number of contexts
without being obliged to reduce
the spectrum of
the composition protocol and
as a consequence, the programmer
assistance
and the
controls which are performed.
One improvement which derives
from
the latter is the
implementation of optional clauses.
This would enable to differenciate
between an
adaptation within the framework
of an existing application and
another one dealing
with concerns to be composed
in order to build an application.
A more long term perspective
is to adapt our model to apply
it to component-oriented
programming
and to model-oriented programming. Footnotes
1 This is the term used in UML to deal
with the various kinds of class.
2 Gamma prefers Subject and ConcreteSubject
instead of Observable and ImplObservable.
3 We use terminology of different programming
languages (Java, Eiffel. . . ) to highlight that our
approach is not restricted to one particular language.
4 If it contains itself
an adaptation target which is abstract, then the adapter is abstract.
5 The examples of adapters presented
in this paper only use a part of this syntax.
6 Everything works as if those classes
were specifying the declaration implements Observer
7 Of course nothing prevents us from
building a new abstract adapter that inherits from an
existing one, either to add some new adaptations or to make some of
its adaptations or adaptation
targets concrete.
8 In the current implementation their
expressiveness relies on the API java.util.regex of Java.
9 Even if, in our example, the associated
behaviour is very basic.
10 The detailed reification of each
adaptation appears in [20].
11 In Java it applies to both classes
and interfaces but for the latter, the method must be abstract
and public
12 One corresponds to the adaptation
specifications and another one to the concerns themselves.
13 The Ph.D Thesis of Laurent Quintian
[20] provides a more detailed study.
14 The treatments to be inserted
use the chosen language (for
us, Java).
ACKNOWLEDGEMENTS
We gratefully acknowledge Karine Arnout (ETH Zurich) for her valuable
comments
and feedback on the paper. REFERENCES
[1] M. Aksit, L. Bergmans, and S. Vural. An object-oriented language-database
integration model: The composition-filters approach. In Proceedings
of
ECOOP’92, LNCS(615), pages 372–395. Springer-Verlag, 1992.
[2] G. Bracha and W. Cook. Mixin-based inheritance. In proceedings
of OOPSLA/
ECOOP 90, 1990.
[3] P. Caro. Adding Systemic Crosscuting and Super-Imposition
to Composition
Filters. Ph.D Thesis, University of Twente, Netherlands, 2001.
[4] P. Cointe. Reflective languages and metalevel architectures.
ACM Comput.
Surveys, 28(4es):151, 1996.
[5] K. Czarnecki and J. Vlissides. Domain-Driven Development.
Special Track at
OOPSLA’03 URL: http://oopsla.acm.org/oopsla2003/files/ddd.html,
2003.
[6] Eclipse fundation. Environnement eclipse. http://www.eclipse.org,
2004.
[7] E. Gamma, R. Helm, R. Johnson, and J. Vlissides. Design
Patterns: Elements
of Reusable Object-Oriented Software. Addison-Wesley Publishing
Co., 1994.
[8] J. Hannemann and G. Kiczales. Design pattern
implementation in java and
aspectj. In proceedings of OOSPLA’02, 2002.
[9] E. Kendall. Role model designs and implementations with
aspect-oriented programming.
In Proceedings of OOPSLA’99, pages 353–369, Denver, Colorado,
United States, November 1999. ACM Press.
[10] G. Kiczales, E. Hilsdale, J. Hugunin, M. Kersten, J. Palm,
and W. Griswold.
Getting started with aspectj. Communications of the ACM, 44(10):59–65,
October
2001.
[11] G. Kiczales, E. Hilsdale, J. Hugunin, M. Kersten, J. Palm,
and W. Griswold. An
overview of aspectj. In Proceedings of ECOOP’01, LNCS(2072), pages
327–353,
Budapest, Hungary, June 2001. Springer-Verlag.
[12] G. Kiczales, J. Lamping, A. Mendhekar, C. Lopes, J. Loingtier,
and J. Irwin.
Aspect oriented programming. In Proceedings of ECOOP’97, LNCS(1241),
pages 220–242. Springer-Verlag, June 1997.
[13] B. Meyer. Object-Oriented Software Construction. Professional
Technical Reference.
Prentice Hall, 2nd edition, 1997.
[14] M. Mezini and K. Ostermann. Conquering Aspects with Casear.
In Proceedings
of the 2nd International Conference on Aspect-Oriented Software
Development
(AOSD’03), Boston, Massachusetts, USA, March 2003, pages 90–99.
[15] Sun microsystems. Java architecture for xml binding jaxb.
http://java.sun.com/xml/jaxb/index.jsp, 2004.
[16] S. McDirmid and W. Hsieh. Aspect-Oriented Programming
with Jiazzi. In
Proceedings of the 2nd International Conference on Aspect-Oriented
Software
Development (AOSD’03), Boston, Massachusetts, USA, March 2003.
[17] H. Ossher, M. Kaplan, W. Harrison, A. Katz, and V. Kruskal.
Subject-oriented
composition rules. In Proceedings of OOPSLA 95, 1995.
[18] H. Ossher and P. Tarr. Hyper/j: Multi-dimentionnal separation
of concern for
java. In Proceedings of ICSE’00, 2000.
[19] R. Pawlak, L. Seinturier, L. Duchien, and G. Florin. Dynamic
Wrappers:
Handling he Composition Issue with JAC. In proceedings of TOOLS’01,
pages
56–65, 2001.
[20] L. Quintian. JAdaptor: Un modèle pour améliorer
la réutilisation
des
préoccupations dans le paradigme objet. Ph.D thesis in Computer
Science, University
of Nice - Sophia Antipolis, France, July 2004. [21] C.
Szyperski, J. Bosch, and W. Weck. Component-oriented programming.
In Proceedings of the workshop on Component-Oriented Programming
at ECOOP’99, LNCS(1743), pages 184–192, Lisbon, Portugal,
June 1999.
Springer-Verlag.
[22] W3C. Xml schema. http://www.w3.org/XML/Schema, 2004.
About the authors
Cite this document as follows: Philippe Lahire, Laurent Quintian:
New Perspective To Improve
Reusability in Object-Oriented Languages, in Journal of Object
Technology, vol. 5, no. 1,
January–February 2006, pages 117-138,
http://www.jot.fm/issues/issues_2006_01/article5
|