Composite


Composites are built up from one superclass
to enable uniform handeling.


This is the abstract component class.
This is the super class for all component
and composite classes. 
-----------------------------------------------------
abstract class AbstractComponent{
    AbstractComposite parent;

    private AbstractComposite getParent(){
        return parent;
    }
    
    public abstract int countBikers();        
}
-----------------------------------------------------


This is the abstract composite class.
The client can treat this class just as it would a 
component class.
When asked to perform component functions it delegates 
to its children.
It caches or delegates to its parent contextual information 
requests.
-----------------------------------------------------
abstract class AbstractComposite extends AbstractComponent{
   private Vector children = new Vector();
    private int bikerCount = -1;

    public AbstractComponent getBiker(int index){
        return (AbstractComponent)children.elementAt(index);
    }

    public synchronized void addChild(AbstractComponent child){
        synchronized (child){
            children.addElement(child);
            child.parent = this;
            changeNotification();
        }
    }


    public synchronized void removeChild(AbstractComponent child){
        synchronized (child){
            if (child.parent == this){
                child.parent = null;
                children.removeElement(child);
                changeNotification();
            }
        }
    }


    public void changeNotification(){
        bikerCount = -1;
        if(parent != null)
            parent.changeNotification();
    }


    public int countBikers(){
        if(bikerCount!=-1)
            return bikerCount;
        int count = 0;
        for(int i =0; i<children.size(); i++){
            AbstractComponent child = (AbstractComponent)children.elementAt(i);
            count += child.countBikers();
        }
        bikerCount = count;
        return bikerCount;
    }
    
}
-----------------------------------------------------


Concrete component class.
-----------------------------------------------------
class Biker extends AbstractComponent{

    public int countBikers(){
        return 1;
    }
}
-----------------------------------------------------


Concrete composite class.
-----------------------------------------------------
class BikerRally extends AbstractComposite{}
-----------------------------------------------------


Concrete composite class.
-----------------------------------------------------
class BikerGang extends AbstractComposite{}
-----------------------------------------------------


Test stub to run it all.
-----------------------------------------------------
class Test{

    public static void main(String[] args){
        System.out.println("class: Test, method: main");

        AbstractComposite bikerRally = new BikerRally();
        
        for(int i =0; i<849; i++)
            bikerRally.addChild(new Biker());

        for(int i =0; i<17; i++){
             BikerGang bikerGang = new BikerGang();
            for(int j =0; j<38; j++){
                bikerGang.addChild(new Biker());   
            }
            bikerRally.addChild(bikerGang);
        }
        System.out.println("biker count is: " + bikerRally.countBikers());
    }
}
-----------------------------------------------------


Here is a tar with the above java classes in it. 
composite.tar