Composite Pattern: Flash AS3 Menu example

If you are serious with Actionscript it is a must to use Design patterns. Why? Because

  • large scripts are broken into smaller reusable pieces,
  • the relation of objects and actions becomes loose, which
  • allows to make changes in a small script instead of having to change a large script.
  • Only the interface is visible to the client.

There is a nice book “Actionscript 3 Design Patterns”, in which taken from other programming languages various design patterns are described with examples. However, my idea is to keep the scripts even more conceiled by using xml and manipulating text, url’s, file names with an xml file. Go to Model View Controller for Flash, if you want to see the example.

The other day somebody had a problem with removing children from a menu. So I thought to write some basic scripts using a suitable design pattern for a menu, which makes it very easy to remove children. The reason is simple, because now the movie is organized and can be controlled. The most suitable pattern, which I could think of, is the Composite pattern, which is similar to the Displaylist or the DOM or tree structure. If you want to know more, check Wikipedia for details.

First we make an outline of the structure of the menu, which you can see here. Even it is a simple menu it is important to see the organization of the final product. The ROOT is the holder of the menu and will be a component. Then we have 5 menuitems, which except for the m4 item has subitems. We create a Component class, which extends Sprite and is the class for items, which have children other than those, which make the design of an object such as a textfield. So we create the MenuItem class, which extends the Component class and associate it with the Sprite for the menuitems. We further create the Composite class, which extends Sprite and is the superclass for the leaf children. Both classes implement the IMenu interface, because there are methods, which both classes share. We create another class, the SubMenuItem class, which extends the Composite class and associate the submenu Sprite with this class. We have basically all classes ready except for the Document class of the movie, which we name Main and extends Sprite. Now we need to write the scripts for the classes.

The MenuItem class

We start with this class and you can see the final class here. The Constructor of this class has three parameters, which are inherited from its superclass, the Component class. Those are for an array to hold the information for the children, then a headline and in case we don’t have any further children we need a url. m4 is such a menuitem. We then create a textfield for the headline and we add button events. We want the menitem to have a shadow on mouseover and remove the shadow on mouseout. We also want that the submenuitems be removed when the client wants to access another menuitem. So we create a function “deleteItems”, which we define in the Component class. When we click on the menuitem we want the submenu to appear, which we do by adding submenuitems. The number of the items, their headlines and urls are stored in the array. We then trigger another method, addItems, which is a method of the superclass. This is important, since the instances need to be stored somewhere to be able to remove them later. In case there are no subitems we trigger a method, showItem, which is also a method of the Component superclass. Now we need to have a closer look at the Component class.

The Component class

The constructor of this class has three parameters, which we already learned earlier. We have a getter function for each of these parameters, which are also part of the interface, since these functions are shared by the Component and Composite classes. Then we declare several internal functions, which should only be visible to the subclass(es), which in our case is only one, the MenuItem class. There is showItem, where we execute for simple reasons a trace function. We would normally use something like navigateURL. Inside this function we have the setParent(this) function, which serves to memorize this instance of the menuitem. If you look at the setParent function then we have a static variable “previousNode”, which associates with this instance. Then we have the addItems (mySub:Composite) function. This function adds individual submenuitem instances to a Vector with the data type “Composite”, since that is the superclass for the SubMenuItem class. We also have here the setParent function for reasons mentioned above. Next we have the deleteItems() function. This function serves to remove the children of the previous menuitem, when a new menuitem was pressed. And now you can see for what we need “previousNode”. We safely remove the children. We can do that in a more sophisticated way with tweens etc. if we feel to.

All other classes

You probably get an idea how this works, so I only place links to the other classes, which are left, the Composite class, the SubMenuItem class, and the IMenu class. However, I will go into more detail for the Main class, which is our Document class.

Main class

We want this menu to be flexible and not do any changes in our scripts, when we want to extend the menu. So we use xml for this. You can see the Menu.xml file here. We load the xml file first, which you can see in the beginning of the Document class. Then we extract all the information. First we create the ROOT of the menu, which is of data type Component and will hold all the children. “xmlData.menuitem.length()” will give us the number of menuitems, which we add to the ROOT. “xmlData.menuitem[i].menusubitem.length() will give us the number of subitems for each menuitem. We can extract the headlines and urls and fill an array, which we add as a parameter to each associated menuitem. Then we arrange the menuitems and add them to to the ROOT. And that concludes this tutorial. You can download all files here.

Leave a Reply

You must be logged in to post a comment.