Hooks, aspect-oriented programming, and design by contract
Phillip J. Eby
pje at telecommunity.com
Sun Jan 27 05:08:34 CET 2002
In article <pan.2002.01.23.10.42.20.136727.1794 at club-internet.fr>,
pedro_rodriguez at club-internet.fr says...
> I checked those docs and I have got some remarks/questions about it :
> - What is the current status of TransWarp ? Will this part of Zope 3 ?
It is an effort entirely independent of Zope, basically my personal Grail
Quest of sorts. :)
As for the status, I'm in the midst of refactoring to make AspectJ-style
pointcuts and advice possible. It's almost done.
> - I get the impression that it got it the wrong way with Aspects :
> + an Aspect (Template) -> creates -> a Component (Class)
> + a Component (Class) -> creates -> a ComponentInstance (object)
In AspectJ, aspects are effectively added to a class hierarchy, but the
class hierarchy is not considered an Aspect. In TW, it's orthogonal and
the class hierarchy is an aspect, too. It's as though in AspectJ you
wrote all the "main" class hierarchy using method introductions, and thus
everything was an aspect. I saw no reason to pick an arbitrary aspect
and single it out as the "class hierarchy".
> Maybe this comes from the influence of AspectJ doc readings but
> aspect concept should be orthogonal to class hierarchy and not mixed
> in this way.
One of the design difficulties I had was defining what the scope of
aspects should be. Many AOP tools assume that the environment of an
aspect-oriented construction is an entire program, i.e. the entire
language runtime environment. I didn't want to require such a global
"weave" environment, because to my mind it would hamper reusability, and
an explicit goal of TransWarp is to facilitate reusability of components
created by other developers.
If I want to use component X two different ways in my application, I
would like to be able to add different aspects to each usage. But if the
scope of aspect weaving is global, I can only end up with one "copy" of
X. (Note that if X is a class, I could use inheritance and create two
versions, then aspectize each, but if X is a family of classes,
inheritance may become impossible.) Thus, I chose to have the TW build
process construct a family of related classes, which can be used
independently of any other class or family thereof. (It seemed to me,
also, that this was an appropriately Pythonic way of doing it.)
> - In fact there is no more class hierarchy as we know it currently.
> It defines its own hierarchy with aspects. Must be missing something
> there, like : why is Aspect3 = (Aspect1+Aspect2)(...) better than
> class Aspect3(Aspect1, Aspect2): ...
That's an implementation-specific thing. I have in fact deprecated
aspect inheritance and indeed the term "aspect" in TransWarp. What TW
does is provide a "build process" which can be used to create entire
families of classes and or instances from meta-level specifications.
Those specifications can be layered together to create more complex
specifications. One layer might define method wrappers for methods
defined in another layer, for example. Thus, TW provides the tools and
environment for doing AOP, but it is not inherently AOP in nature.
The bulk of the things I use it for are actually more for generating
various things from metadata, and assembling components to construct
applications. Originally, I thought it would be more AOP-oriented, and
the early versions had built-in notions of aspects which have since
vanished from the code.
TW is really more of a generalized concept of building software
components from specifications. It just so happens that AOP is one of
the things you can do with it. However, I *have* just got through adding
the notion of "advisors" this week (on a CVS branch), which at some point
will become the basis for AspectJ-style "advice". However, if someone
doesn't like the way I implement "advice", they are free to write their
own advisors that implement advice differently. It's a microkernel sort
of approach; as long as your "advisor" objects implement the interface
needed by the build framework, they can inform, modify, and postprocess
methods, classes, etc. as they are built. This can include bytecode
rewriting, if you're so inclined.
The thing TW has over writing extensions to the compiler package is that
compiler extensions from different people aren't (generally speaking)
usable against the same code base. But Advisor, Specification, and
Interpreter objects for TW can be implemented by different parties and
still participate in the same build process.
> - TransWarp looks to be defining metaclasses and I got the feeling that
> metaclasses can provide some helper methods to aspects, but are not
TW uses metaclasses for specifications, but it's pretty much transparent
to the user. The metaclass instances get turned back into "real" classes
(or ExtensionClasses, or even other metaclass instances) during the build
process. The metaclass instance form can be more flexible than a "real"
class, but whether you use a real class or a metaclass instance, TW
interprets it in more or less the same way.
More information about the Python-list