Subject: AOP ontology
From: lieber@ccs.neu.edu
Date: Sat Jan 12 2002 - 09:05:33 EST
Hi Gregor:
on Thursday we had a discussion in our seminar of your
ontology and our additions to it.
The first row (dynamic JPM) and third row (static JPM, open classes)
were not controvercial. The second row (static JPM, specialized for adding
only traversal methods to classes) was questioned by Doug and Mitch.
See Demeter home page in seminar/2002/jan10/ontology-2-karls-version.ppt
The black line pertains to Demeter/C++, DemeterJ and
DJ, and the blue and red lines refer to Demeter/C++ and
DemeterJ. The red line is a specialization of the blue line.
The blue (and red line) line is used to implement the black line,
in the case of DemeterJ using a weaving language also used
for COOL and RIDL.
Mitch writes:
>The fact that we can implement a dynamic join point model by using
>static weaving should not come as any surprise-- after all, that's one
>of the standard ways of implementing a dynamic JPM: compiling the
>calls to advice code into procedure or method calls to be added in the
>right places.
Doug's point is that he does not view a traversal as crosscutting
because you can think of an adhoc implementation that is not scattered:
it puts the traversal all
into one method (heavily violating the Law of Demeter).
Doug also says:
>The other reason is that even in the case where the ad hoc
>implementation is scattered, it does not modify the public interface
>of the classes that the traversal methods are attached to. I.e. no
>one is supposed to call these helper traversal methods except for the
>top-level traversal method. That's why I dislike your implementation
>below that attaches advice to these helper traversal methods:
> pointcut counting(): target(Vertex) && call(* allInh_Cd_graph_trv_bef (UniversalVisitor));
This is very interesting to me because if we cannot agree on whether
a traversal is crosscutting or not, we will have similar problems
with other concerns than the traversal concern.
For me the traversal concern is crosscutting because all ad-hoc implementations
I know of are either scattered across multiple classes or localized
in one class and information revealing about the classes. So independently
of the implementation, I can always learn a lot about the structure
of the classes.
This is also true for the DJ implementation:
new TraversalGraph(classGraph, travspec).traverse(o,v);
When I study that traversal graph, I will find basically
k copies of the class graph where k is the number of edges in travspec.
After this discussion, Matthias joined the seminar and through
another argument related to EJBs, he said: "crosscutting is always
relative to some implementation".
He said that aspects are code
that is distributed across "modules" and that therefore aspect orientation
must be determined relative to some basis.
Maybe the following is a step towards a definition of crosscutting:
A concern CO is crosscutting at level g1 and g2 modulo a
class graph G if for each
implementation of CO we deduce at least the fraction g1
of all edges and the fraction g2 of all nodes of G.
A traversal is crosscutting modulo the class graph
at level fraction of edges in traversal graph
and fraction of nodes in traversal graph because an implementation
which leaves out any one of them will be wrong.
The above definition is only modulo a class graph which is
an important special case.
It is interesting to think about generalizing to the call graph.
A related question is:
If we have in AspectJ: cflow(pcd1) && pcd2 how much information
can we get from the generated Java code
about the static call graph that is involved in the
above cflow?
-- Karl
============ message to Gregor an Mitch on Jan. 10 below
Here is an example that explains the two Demeter rows.
The static JPM row we will do in DemeterJ and the
dynamic JPM row we will do in AspectJ without touching the
DemeterJ code. Using two different implementation technologies
more clearly separates the two JPMs.
The task is to count the number of
inheritance relationships in a UML-style class diagram:
Cd_graph {
traversal allInh(UniversalVisitor v) {
via Alternat to Vertex;
}
int countInhRels() {{
this.allInh(new UniversalVisitor(){});
return 0;
}}
}
The purpose of this code is to produce the traversal methods
using an empty visitor that does not do anything interesting.
This is a use of the first join point model where a traversa
strategy introduces traversal methods to the classes in the
scope of the traversal.
Now, to say what needs to be done in addition to the traversal
we use the JPM of AspectJ:
(we have to know a little bit about the naming conventions
in the generated Java code)
aspect Count {
static int total;
pointcut init(): target(Cd_graph) && call(int countInhRels());
pointcut counting(): target(Vertex) && call(* allInh_Cd_graph_trv_bef (UniversalVisitor));
before():init() {total=0;}
before():counting() {total++;}
int around(): init() {
thisJoinPoint.proceed();
return total;
}
}
Back to Gregor's other point: I can see why he prefers "signatures"
over "class names". But what really happens here is that you use
a flow specification (NOT a cflow) that is like a cflow but
in a different kind of graph. A+ is basically flow(A) along subclass edges
in the class graph (and not in the call graph).
This is explained better in the slides I pointed to earlier.
-- Karl
This archive was generated by hypermail 2b28 : Sat Jan 12 2002 - 09:10:00 EST