You are not logged in Log in Join
You are here: Home » Members » Phillip J. Eby's Zope Center » My Wikis » TransWarp Wiki » IntroToAOP

Log in
Name

Password

 
 

History for IntroToAOP

??changed:
-
What Is Aspect-Oriented Programming?

 Most of the major paradigm shifts in programming have come about from seeking ways to improve the clarity, flexibility, and reusability of written code.  These paradigm shifts have basically been:

 * Subroutines and macros -- Automated reuse of code.

   Structuring concept: code snippets.

 * Structured Programming -- Black-box use of provably correct code.  

   Structuring concepts: single-entry/single-exit structures and modular decomposition.

 * Object-oriented Programming -- Black-box reuse of coupled code and data structures.

   Structuring concepts: the abstract data type, the class, and the interface contract.

 * Aspect-oriented Programming -- Reuse of aspects that crosscut entire families of classes.

   Structuring concept: the "aspect", an area of concern which applies to multiple data types in an application.

 Each paradigm shift has expanded our concepts of what "modularity" is, and what the "fundamental units" of coding and reuse are.  AOP simply takes this to the next logical level, by addressing "aspects" rather than just "objects" as the unit of reuse.


So what's an "Aspect", then?

 An "aspect" is an "area of concern" that cuts across the structure of a program.  For example, data storage is an aspect.  User interface is an aspect.  Platform-specific code is an aspect.  Security is an aspect.  Distribution, logging, class structure, threading... they're all aspects.

 One way to look at aspects is that they reflect decisions you must make about implementing a program.  In any of the pre-AOP paradigms, these would be decisions you'd have to make before you started coding, because the code that implements those decisions has to be "tangled" into all the other code.  You can't start writing a web-based, ZODB-stored application using the Zope UI framework and then halfway through decide you'd really rather have a wxPython client GUI accessing a CORBA server to talk to an RDBMS.

 Of course, if you thought about it beforehand, you probably could have broken up your classes and code in such a way as to make parts reusable for each environment.  But this adds a lot of overhead to your design process, and you'll probably end up with repeated inheritance trees and lots of little hooks and methods that call other methods just so parts can be overridden.

 AOP lets you deal with each of these decisions seperately, by creating an aspect (or set of aspects) for each area of concern.


But what does AOP let me do that OOP doesn't?

 If you mean, what does it let your programs do that OOP doesn't, absolutely nothing.  But then, neither does OOP let your programs do anything that couldn't be done with a structured program, nor does structured programming let your programs do things that you couldn't achieve through spaghetti coding... if you worked at it hard enough.

 But if you mean, what do you get from AOP as compared to OOP, then some of the answers are:

 * Enhanced re-use -- When you seperate the problem-domain abstractions from your implementation details, both parts become more reusable

 * Enhanced modularization and localization of concerns -- code is easier to read, understand, and maintain, because code that deals with a particular area of concern is grouped together as a unit.

 * Enhanced flexibility -- The ability to create and "weave in" entirely new aspects to accomplish different results.  For example, a testing aspect that replaces database accesses with data read from and written to test files.

 Here's a more vivid example.  Have you ever wanted to use a class library that somebody created, that had a part you didn't like (like an assumption of in-memory data structures), but which you couldn't take out because it was spread through all the classes?  Or, which didn't have a part which you desperately needed (like thread-safety), but couldn't put in without changing all the classes? AOP makes it possible for people to create class families that do just one thing (focus on one "area of concern"), and then are cleanly combinable with other families that address other areas of concern.  And !TransWarp's implementation of AOP actually does pretty well at letting you retrofit existing Python class hierarchies into aspects, too.  (It's better at adding in features than taking them out, though.)


What's the current state of AOP technology?  What tools or languages are available?

 AOP is a very young technology, comparable to where OOP was about 15-20 years ago.  While OOP terminology today is fairly well established and tool support is mature, AOP technology is still very much being invented.  Many of the tools and languages for doing AOP are experimental or academic in nature, and there are several schools of thought on how to define aspects and do aspect weaving.  Current approaches include:

 * Subject-Oriented Programming -- This approach is probably the closest in spirit to !TransWarp's.  See http://www.research.ibm.com/sop/

 * Composition Filters -- Implementing aspects using message filtering and wrapper/adapter objects.  See http://trese.cs.utwente.nl/composition_filters/

 * Demeter/Adaptive Programming -- A subset of AOP concerned primarily with the aspect of structural relationships between classes.  See http://www.ccs.neu.edu/research/demeter/

 Most of the existing tools deal only with Java, C++, or Smalltalk.  At the present time, !TransWarp is the only attempt we know of to create an industrial-strength AOP solution for Python.


So how does !TransWarp implement AOP?

 In !TransWarp, aspects are represented as "class families" - a set of classes which inherit from or instantiate each other - stored in an Aspect object.  Aspect objects are themselves defined using Python "class" statements, or by adding two existing aspect objects together (e.g. 'AspectThree = AspectOne + AspectTwo').  Aspects can also be created programmatically using an AspectMaker object.

 A !TransWarp aspect object is not a class or class family, even though it "looks like one" in source code.  To create an actual class family, you must call the aspect to instantiate it.  An example that demonstrates some core !TransWarp features is shown below::

    from TW.Aspects import Aspect

    class PaintingObjects(Aspect):

        """An aspect describing paintable things"""

        class paintableThing:
            """Things we want to paint"""
            # no implementation here, this isn't an implementation aspect
            pass 

        class Sky(paintableThing):
            name = "sky"
            color = "blue"

        class Grass(paintableThing):
            name = "tuft of grass"
            color = "green"

        class Dog(paintableThing):
            name = "dog named Sparky!"
            color = "black and white spotted"

        def __init__(self):
            self.things = self.Sky(), self.Grass(), self.Dog()


    class BasicPainter(Aspect):

        greeting="Hello!"

        def paint(self):
            print self.greeting;           
            for thing in self.things:
                thing.paint()
            print


    class LazyPainter(BasicPainter):

        greeting = "Yawn...."

        class paintableThing:
            def paint(self):
                print "A %s %s would go here, if only I had the energy..." \
                      % (self.color,self.name)


    class AngryPainter(BasicPainter):
        greeting = "Oh yeah?"

        class paintableThing:
            def paint(self):
                print "What makes you think I want to paint a stupid %s %s?!" \
                      % (self.color,self.name)


    class Surrealism(Aspect):

         class Sky: color = "polka-dot pink on purple"
         class Grass: color = "tiger-striped"
         class Dog: color = "melting"



    # Adding aspects together makes aspects, but to make a class you must
    # call the resulting aspect to "weave" it into an actual class.

    LazyPaintingClass = (PaintingObjects + LazyPainter)()
    AngryPaintingClass = (PaintingObjects + AngryPainter)()

    SurrealAndLazyClass = (PaintingObjects + Surrealism + LazyPainter)()
    SurrealAndAngryClass = (PaintingObjects + Surrealism + AngryPainter)()

    LazyPaintingClass().paint()
    AngryPaintingClass().paint()
    SurrealAndLazyClass().paint()
    SurrealAndAngryClass().paint()


When run, you should see the following::

    Yawn....
    A blue sky would go here, if only I had the energy...
    A green tuft of grass would go here, if only I had the energy...
    A black and white spotted dog named Sparky! would go here, if only I had the energy...

    Oh yeah?
    What makes you think I want to paint a stupid blue sky?!
    What makes you think I want to paint a stupid green tuft of grass?!
    What makes you think I want to paint a stupid black and white spotted dog named Sparky!?!

    Yawn....
    A polka-dot pink on purple sky would go here, if only I had the energy...
    A tiger-striped tuft of grass would go here, if only I had the energy...
    A melting dog named Sparky! would go here, if only I had the energy...

    Oh yeah?
    What makes you think I want to paint a stupid polka-dot pink on purple sky?!
    What makes you think I want to paint a stupid tiger-striped tuft of grass?!
    What makes you think I want to paint a stupid melting dog named Sparky!?!

For more details on doing AOP with !TransWarp, check out the AOPTutorial.

<hr solid id=comments_below>


occam (Jan 25, 2002 1:14 am; Comment #1)  --
 Link: JavaWorld article (first of three introducing AspectJ) introducing AOP with a few (Java) AspectJ examples but mostly another good intro to the merits of AOP.
   http://www.javaworld.com/javaworld/jw-01-2002/jw-0118-aspect.html