Recipe18.1.Implementing the Composite Pattern


Recipe 18.1. Implementing the Composite Pattern

Problem

You want to apply the composite pattern using AspectJ.

Solution

The composite pattern provides the capability to group objects together in a collection and interact with the group as a whole in a similar manner as you would interact with an individual member of the group.

Example 18-1 uses the Director aspect-oriented design pattern (see Chapter 23) to provide a generic implementation of the composite pattern using AspectJ.

Example 18-1. Using an aspect to define the composite pattern
public abstract aspect CompositePattern  {    public interface Component     {    }    protected interface Composite extends Component     {    }    protected interface Leaf extends Component     {    }         private WeakHashMap perComponentChildren = new WeakHashMap( );    private Vector getChildren(Component s)     {       Vector children = (Vector) perComponentChildren.get(s);       if (children == null)        {          children = new Vector( );          perComponentChildren.put(s, children);       }       return children;    }    public void addChild(Composite composite, Component component)     {       getChildren(composite).add(component);    }    public void removeChild(Composite composite, Component component)     {       getChildren(composite).remove(component);    }    public Enumeration getAllChildren(Component c) {       return getChildren(c).elements( );    }    public interface Visitor {       public void doOperation(Component c);    }    public void recurseOperation(Component c, Visitor v) {        for (Enumeration enum = getAllChildren(c); enum.hasMoreElements( );) {                Component child = (Component) enum.nextElement( );                v.doOperation(child);        }    }    public interface FunctionVisitor     {       public Object doFunction(Component c);    }    public Enumeration recurseFunction(Component c, FunctionVisitor fv)     {       Vector results = new Vector( );       for (Enumeration enum = getAllChildren(c); enum.hasMoreElements( );) {       Component child = (Component) enum.nextElement( );         results.add(fv.doFunction(child));       }       return results.elements( );    } }

Discussion

The CompositePattern aspect defines the Composite and Leaf interfaces to be applied to classes within your application playing those roles. The aspect uses the visitor pattern to recursively visit and work with each of the components of a composite.

Figure 18-1 shows the structure of the CompositePattern abstract aspect and the interfaces and behavior that it defines to support the composite design pattern.

Figure 18-1. The CompositePattern aspect and the interfaces it defines for the design pattern's roles


This CompositePattern abstract aspect is extended into specialized subaspects that specify the classes that play the Composite and Leaf roles. Example 18-2 shows how the abstract CompositePattern aspect can be applied for a specific application.

Example 18-2. Applying the CompositePattern aspect to a target application
public aspect GraphicsComposite extends CompositePattern  {    declare parents : Window implements Composite;    declare parents : Line implements Leaf;    declare parents : Rectangle implements Leaf;        public void Component.draw(PrintStream s)    {       s.println("Drawing: " + this);    }        public void Composite.draw(final PrintStream s)    {       s.println("Composite: " + this);       GraphicsComposite.aspectOf( ).recurseOperation(this, new Visitor( )          {             public void doOperation(Component c)             {                c.draw(s);             }          });    }        public void Leaf.draw(PrintStream s)    {       s.println("Drawing Leaf: " + this);    } }

Figure 18-2 shows an example set of application classes before the GraphicsComposite aspect is applied.

Figure 18-2. The Window, Line, and Rectangle business logic classes


Figure 18-3 shows the effects of applying the GraphicsComposite aspect shown in Example 18-2 to a set of application classes.

Figure 18-3. The static structure after the composite pattern has been applied to the Window, Line, and Rectangle classes


Figure 18-4 shows how the new composite behavior of the Window class is interacted with in an example application.

Figure 18-4. Using the new composite behavior of the Window class


See Also

More information on the extension of existing classes using aspects can be found in Chapter 16; the Director aspect-oriented design pattern is explained in Recipe 23.3.



AspectJ Cookbook
Aspectj Cookbook
ISBN: 0596006543
EAN: 2147483647
Year: 2006
Pages: 203
Authors: Russ Miles

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net