Skip to content
October 8, 2008 / Shrikant Patil

Structural Design Patterns : Composite Design Pattern

The Composite Pattern is considerable pattern of Structural Design Patterns group. Composite pattern is solution for building complex systems which are made up of lots of smaller components.  To understand the concept of Composite Pattern we need to understand the terms;
1) Components and
2) Composites

Before digging more into the topic let us have a look at the theoretical definition of Composite Pattern;

Definition: The composite pattern allows us to compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and composition of objects uniformly.

By the definition, the objects are composed in the form of tree structures. As we know tree structures include parent and child nodes (branches and leafs).

We know the basic term that, components make up the system. In Composite pattern, the components are represented in the form of tree. Components are the individual nodes of the tree which doesn’t have any child nodes and Composite components are composition of one or more child nodes (leaves). Mean that composition must have at least one of child node or composition node. A composite node may also contain one or more other composite nodes.

Assume that computer is a system, it is made up of many individual components like hard disk, motherboard, Graphics Card, monitor etc. These components of a computer system also contain its own components for Example Motherboard contains RAM, Processor etc. So Mother Board is Composite component and RAM, Processor are individual components.

Again looking at the definition, Composite lets clients treat individual objects and composition of objects uniformly – system considers both composite and individual components as similar.  So client will get an interface where there is no need to think about component or composite component while adding or removing the components of the system.

Lets us have a look at class diagram of Composite Pattern;
Component Class:
The Component (Abstract) is interface for both Composite and Leaf classes. Here the Component class is an Abstract class, which provides implementations for the both Composite and Leaf objects. Also note that the Abstract component class defines the methods: Add(), Remove() and GetChild() methods which are used by the client to create and interact with complex system.

Composite Class:
Composite class is derived form the Abstract Component class and overrides the Add(), Remove() , getChild() and Operation() methods. It really mean to override these methods in this class, because the Composite Component only can have one or more individual or Composite components, so addition, removal and traversing to specific leaf inside a composite are required functionalities in Composite class. Composite holds more than one or more Leaf or other campsite objects in an array.
The overridden Operation() method is important implementation of the Composite Pattern. We know that all Leaf objects have Oparation() method implemented. So when client request Operation() method of this Composite Class, it iterate through all of its Leaf objects and calls Operation() method on those individual Leaf Objects.

Leaf Class:
Leaf Class is also derived from the Abstract Component class, and override only Operation() method. This is because, the leaf is a individual component without any child nodes. So it doesn’t mean to have add(), remove() and GetChild() methods in this class.

I will try to explain the pattern with an example. In this example I am going to create a MENU which includes many sub menus.
1) Creating Abstract Component Class
Here I am creating Abstract MenuComponent (Component) class which provides an interface for MenuItem (Leaf) and MenuComposite (Composite) classes. The class defines signatures of

  • addMenuItem() – which is used to add a MenuComponent (Leaf) to the MenuComposite (composition) which is get overridden only in MenuComposite(Composite) class.
  • Abstract showTitle() – which is get overridden in both MenuItem (Leaf) and MenuComposite (Composite) Classes.

package flexScript
{
    import mx.controls.menuClasses.MenuItemRenderer;
    //Abstract class, shoud be subclasses and not instantiated
    public class MenuComponent
    {
        public function addMenuItem(m:MenuComponent):void{
            throw new Error("Operation Failed");
        }
        //Abstract method overriden in subclasses
        public function showTitle():void{

        }

    }
}

2) Creating Leaf Class:
Here I am creating MenuItem (Leaf) class which extends the Abstract MenuComponent (Component) class. It defines a private variable to hold the name of the title to which constructor of the class assign the value of its parameter. The class overrides the showTitle() method which simply traces the title of the MenuItem assigned.


package flexScript
{
    //Leaf class extends Abstract Component class
    public class MenuItem extends MenuComponent
    {
        private var titleString:String;
        public function MenuItem(title:String)
        {
            this.titleString = title;
        }
        //override Abstract showTitle method
        override public function showTitle():void{
            trace(this.titleString);
        }
    }
}

3) Creating Composite:
Here I am creating MenuComposite (Composite) class which is derived from Abstract MenuComponent (Component). Class defines two private variables, one which is used to hold the title of the composite menu title and another one is type of ArrayCollection, which is used to hold all MeanuItem (Leaf) of the Composite.
Constructor assign the value of parameter passed to title variable and initializes the array. Overridden addMenuItem() method simply adds the passed MenuComponent type object to array.
The important overridden showTitle of this class, iterates through each items if the array and calls showTitle() method of each item, which traces title of each sum-level menu item titles.


package flexScript
{
    import mx.collections.ArrayCollection;
    //composite class extends Abstract Component class 
    public class MenuComposite extends MenuComponent
    {
        private var titleString:String;
        //define a array to hold all sub menu items of the composition
        private var menuList:ArrayCollection;

        public function MenuComposite(title:String)
        {
            this.titleString = title;
            menuList = new ArrayCollection();
        }

        //override public function addMenuItem
        override public function addMenuItem(m:MenuComponent):void{
            menuList.addItem(m);
        }

        //override showTitle method to show title of all
        // sub menu items
        override public function showTitle():void{
            trace(this.titleString);
            trace("-------------");
            //Iterate through all sub menu items
            for each(var t:MenuComponent in menuList){
                //call showTitile of each sub menu item
                t.showTitle();
            }
        }
    }
}

4) Creating Client
Client is an MXML application. Client at fist create a new MenuComposite (Composite) object for FILE menu. After that it starts creating sub level of menuItem and MenuComposite objects and adds them to the main FILE MenuComposite.


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" creationComplete="init()">
    <mx:Script>
        <!&#91;CDATA&#91;
            import flexScript.*;

            private function init():void{
                var FileMenu:MenuComposite = new MenuComposite("File Menu");
                //create NEW sub menus
                var fileNewMnu:MenuComposite = new MenuComposite("New");
                fileNewMnu.addMenuItem(new MenuItem("MXML Application"));
                fileNewMnu.addMenuItem(new MenuItem("MXML Component"));
                fileNewMnu.addMenuItem(new MenuItem("ActionScript Class"));
                fileNewMnu.addMenuItem(new MenuItem("ActionScript Interface"));
                fileNewMnu.addMenuItem(new MenuItem("CSS File"));
                FileMenu.addMenuItem(fileNewMnu);
                //create OPEN menu
                var fileOpenMnu:MenuItem = new MenuItem("Open");
                FileMenu.addMenuItem(fileOpenMnu);

                //create Import menu
                var fileImportMnu:MenuComposite = new MenuComposite("Imoprt");
                fileImportMnu.addMenuItem(new MenuItem("Flex Project"));
                fileImportMnu.addMenuItem(new MenuItem("Skin ArtWork"));
                fileImportMnu.addMenuItem(new MenuItem("Web Service"));
                FileMenu.addMenuItem(fileImportMnu);

                //create exit menu
                var fileExitMnu:MenuItem = new MenuItem("Exit");
                FileMenu.addMenuItem(fileExitMnu);

                //call showtitle method of main FILE menu

                FileMenu.showTitle();

            }
        &#93;&#93;>
    </mx:Script>
</mx:Application>

Here is the output of the application.
File Menu
————-
New
————-
MXML Application
MXML Component
ActionScript Class
ActionScript Interface
CSS File
Open
Imoprt
————-
Flex Project
Skin ArtWork
Web Service
Exit

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: