[aosd-discuss] On crosscutting

Cristina Videira Lopes lopes at ics.uci.edu
Tue Feb 28 02:58:20 EST 2006


Let me continue with more considerations about crosscutting, scattering,
aspects, etc. and what all that implies for aspect-oriented software
development, according to my view of the world. I don't know if anyone is
reading this, but here it goes anyway. It's a very long message, almost an
essay... I've been meaning to write something like this for a long time.
This recent thread, plus a need to procrastinate on other important things,
made me do it now :)

I assume we all have now a common intuitive understanding of crosscutting,
both wrt a representation and in its representation-free form. Are these two
completely different things? And which one captures "aspects"?

I think there is a common description of these two kinds of crosscutting,
but the ways of dealing with them can be quite different. When we have
scattering/tangling in a representation, it's because one concern X can't be
completely described in that representation without refering to the other
concern Y. When we have crosscutting concerns, it's because one concern X
can't be completely specified without refering to implementations of the
other concern Y.

There's a common template for crosscutting in here: X needs pieces of Y. But
the "pieces of Y" have different natures. In the representational case, they
are abstractions of Y; in the other case, they're a projection in X of
implementation options made in Y.

---

Before I expand on this, let me comment on Bill Harrison's features/concepts
message, and how it fits or not in this conceptual framework.

There are two things going on. One is the feature interaction: maybe we need
to add or change something in the auto-dial feature because of the
speed-dial feature or vice-versa. The other thing is the representation of
the system: if I represent the system using features as primary
decompositions, I have to refer to concepts and vice-versa. The latter is
clearly a representational crosscut, and an important one, especially in OO
modeling that sees concepts, rather than features, as the primary
decomposition. The former, the feature interaction problem, well, I don't
think it can be considered a "crosscut" in general. Looking at features as
modularizable concerns (say, using a procedural model that captures each
feature in a component), I think that's an ordinary interaction problem: if
you add a new component (feature) to the system, then you have to specify
how the existing components (features) will interact with it. I don't see
that as a crosscuting concern, I see it as normal system development done
within a potentially serious representational mismatch, especially if you're
using OOP. I mean, it would be great if all the features interacted only
with the application controller (the main method or similar), but sometimes
they interact with other features and so you have to integrate them.

In summary, I don't think that features or their interactions are "aspects
of the application", in general: they are... features, different things that
the application does. Some features depend on other features, some don't,
and that's only normal. Their representation in the artifact may result in
several "aspects of the representation". More on this later. However, a
feature can be an "aspect of the application" if other features depend on
its implementation options, not just on its abstract description.

(Aside #1. I've recently been involved with a MS Access application that had
dozens of features. The developer added those features over a number of
years. The good thing about Access is that you can see the feature code in
mainly two places, a form and a report, rather than being scattered all over
different modules. He could configure different incarnations of this
application containing combinations of features just by checking boxes.
Aside #1.1. I don't know why anyone would want to develop a feature-full
system using the objects as primary decompositions...)

---

When the crosscut is wrt a representation, we can eliminate its
scattering/tangling effects by using another representation that describes
the system in a different way but we don't get rid of crosscutting or
tangling/scattering; they morph. For example, consider people and cars and
relations among the two. Here are three ways of describing what's going on:

1-->
"Alice is a woman and has a blue car; Bob is a man and has a grey car. 
Cars can be blue, grey or red; they have a fuel engine that works like this:
<...>." 
2--> 
"Alice is a woman; Bob is a man. 
Cars can be blue, grey or red; they have a fuel engine that works like this:
<...>; a blue car is owned by Alice and a grey car is owned by Bob."
3-->
"Alice is a woman; Bob is a man. 
Cars can be blue, grey or red; they have a fuel engine that works like this:
<...>.
Alice has a blue car and Bob has a grey car."

These are 3 different representations of the same thing.

In the first representation, the car concern crosscuts the people concern.
As a consequence, it's hard to figure out all the people who have what cars.
In the second representation, that effect disappeared. Instead, it's the
people concern that crosscuts the car concern. As a consequence, it's hard
to figure out everything that a person entails.

(Aside #2. This is the classic complaint we hear about aspectj, for example.
That it pulls out pieces of code into a module, solving some
tangling/scattering effects, but introducing new unwanted scattering
effects.)

In the third representation, both of those effects disappeared, but we
introduced a third sentence that encapsulates the relations between people
and cars. The crosscut morphed again: now it's this third sentence that
refers to people and cars. We still have tangling (in this third sentence)
and the scattering (of cars and people) is arguably worse.

(Aside #3. About the so-called "aspect paradox" (was it Karl that wrote
that?): I don't quite see any paradox. The crosscut doesn't go away when you
use a different representation: it morphs into different scattering/tangling
effects.)

So, does that mean that there is something more fundamental in here that is
representation independent? Yes. The relations between people and cars are
fundamental. Those constitute the *configuration* of the system, i.e. how
and when the concerns *use* each other, and we can never get rid of that.
This relates back to the feature interaction problem, an instance of the
same thing.

But what about the crosscutting concerns that are independent of
representation? Does this morphing phenomenon happen too?

The easy answer is no -- they exist before any representation exists. But
you shouldn't be satisfied with this answer, it's too simple. The answer is
actually yes-but-no, so let me give a longer explanation. 

In the example above (cars and people), people and cars were composed using
a uniform interface to every implementation option of those parts. When this
is the case, then any associated crosscuts are about configurations -- by
"configurations" I mean points at which one part binds with an abstraction
of the other part (not just structural relations as in the simple example
above, it can be more complicated than that). The configurations are
inherent, we can't get rid of them; their scattering/tangling effects are
different depending on the representation. 

It's tempting to say that the best representation is one that modularizes
the configurations, but that's very naïve. One modularizes something so that
the implementation can change independent of the other modules; that's not
the case here: the configurations are not independent, they're inherent to
the parts they configure. So if you choose to modularize them you gain in
seeing the configurations, but you loose the ability to easily see
everything entailed in each concern. There's a tradeoff here.

In the case of the localization system and the games, the crosscut is at
another level: one part can't be specified without knowing about
implementations of the other. So the crosscut is not about configuration;
it's about specification of the components, i.e. what they do. This is
considerably more subtle. Here's a simplified example:

"Alice is a woman and has a blue car; if the car is an SUV she drives it in
the mountains; if the car is a Corolla, she takes her children to school.
Cars are such and such..."

Of course, I've just embodied the situation in a certain representation (the
sentences above), and so you can raise the representation issue again. So,
instead we can say:

"Alice is a woman.
Cars are such and such...
Alice has a blue car; if the car is an SUV she drives it in the mountains;
if the car is a Corolla, she takes her children to school."

The crosscut between people and implementations of cars didn't move a bit,
and the tangling effects moved around, just like in the other example. So,
what's my point? - there doesn't seem to be any differences here wrt the
other example. Ah, but there are. In this case I have the additional option
to represent the situation like this:

In one instance (SUV), "Alice is a woman and has a blue car which she drives
in the mountains."
In another instance (Corolla), "Alice is a woman and has a blue car with
which she takes her children to school."

Or like this:

In all instances, "Alice is a woman and has a blue car."
In one instance (SUV), "Alice drives her car in the mountains."
In another instance (Corolla), "Alice takes her children to school in her
car."

The crosscut between people and implementations of cars didn't go away
either. However, from the first two representations to these last two, the
tangling between car implementations and people changed in a funny way: it
was externalized! (the "in one instance, other instance" thing). So in
practice, the tangling was removed from the behaviors' specification (the
parts within quotes).

We can't do this externalization trick for purely representational
crosscuts, we'd be loosing information and the system would be
underspecified.

Here’s the punch line, finally :)

Unlike in the other case of representational crosscuts, I have no doubt that
the third and forth representations here, the ones with the externalization,
are much better than the first two. Why? Because we know that Alice cannot
have both an SUV and a Corolla in the same system. Including those
conditionals in the behavior of the system -- whatever representation you
choose -- is an unecessary tangle, a redundancy, a break in encapsulation,
an "error" even. Bad, bad, bad.


****

SO, GREAT. What does this mean for AOSD? Here are some semi-random
conclusions.

1) The word "aspect" should not be used in isolation. Aspects are always
aspects of something - the something may vary. So we can talk about aspects
of the specification, of the design, of the implementation - all these are
about representations, and we sure need support for these; and we can talk
about aspects of the application -- these are the ones that have an effect
on what the application ends up being. (btw, there's a related concept in
the Software Engineering literature, architectural variants, maybe?) 

2) These architectural variants (I like this term) are a real pain in the
neck to deal with, and a language like aspectj can help, so can Ruby,
Smalltalk and application-specific languages. Fortunately, not many
applications have architectural variants and, when they do, it's only a few
variants. Still they can have a multiplicative effect, so, again they are a
total pain in the neck, and if you have them, you better think out of the
box before you start designing your solution or your system will be
unmaintainable. The representational crosscuts, on the other hand, are a
(maybe lesser?) plague that no application can escape. That's why everybody
ressonates with them. They are a consequence of the dumb programming
environments that we inherited from 50 years ago.

3) I constantly see people using aspectj and the like to capture
representational crosscuts, and I cringe. This use is, in part, an
overreaction to the realization that there are alternative representations
of the same thing. Yes, there are. But that doesn't mean that one is better
than the others.

4) The representational crosscuts are best supported by a *programming
environment* that can perform transformations on representations, ideally
back and forth, but at least forth. I see a huge opportunity for tools of
this kind. 

5) Join points, whatever their realization, are a great concept, and
absolutely necessary for representational crosscuts. Crosscutting concerns
need more than that: they join with other concerns not just at points, but
in "lines", i.e. continuous points that are projections of one concern's
implementation options in another concern. (aspectj has something like that
in the form of intertype declarations, so does Ruby and other languages)

6) I don't think that XPIs or related ideas, as presented so far, help much
(sorry Kevin and Jonathan!). In the case of representational crosscuts,
there are no "aspect programs", as such (well, there are in aspectj, of
course, if you use it to capture representational crosscuts, but not in
general). In the case of architectual variants (= crosscutting concerns),
there are no guarantees whatsoever that the different implementations of a
concern affect the rest of the system in exactly the same lines (points) -
that's very unlikely, actually. And if that were to happen there are
traditional techniques to deal with that (bridges, hooks, etc.)

-Crista





More information about the discuss mailing list