SDSU CS 635: Advanced Object-Oriented Design & Programming
Spring Semester, 1998
Composite

To Lecture Notes Index
© 1998, All Rights Reserved, SDSU & Roger Whitney
San Diego State University -- This page last updated 21-Apr-98

Contents of Doc 15, Composite


Reference slide # 1
Composite slide # 2
...Example - Motivation slide # 2
...Issue: WidgetContainer Operations slide # 6
...Explicit Parent References slide # 7
...Applicability slide # 8
...Java Use of Composite - AWT Widgets slide # 9


Reference


Design Patterns: Elements of Reusable Object-Oriented Software, Gamma, Helm, Johnson, Vlissides, 1995, pp 163-174
Doc 15, Composite Slide # 2

Composite

Example - Motivation

GUI Windows and GUI elements



How does the window hold and deal with the different items it has to manage?


Widgets are different that WidgetContainers


Doc 15, Composite Slide # 3
Bad News Implementation

class Window
     {
     Buttons[] myButtons;
     Menus[] myMenus;
     TextAreas[] myTextAreas;
     WidgetContainer[] myContainers;
     
     public void update()
          {
          if ( myButtons != null )
               for ( int k = 0; k < myButtons.length(); k++ )
                    myButtons[k].refresh();
          if ( myMenus != null )
               for ( int k = 0; k < myMenus.length(); k++ )
                    myMenus[k].display();
          if ( myTextAreas != null )
               for ( int k = 0; k < myButtons.length(); k++ )
                    myTextAreas[k].refresh();
          if ( myContainers != null )
               for ( int k = 0; k < myContainers.length(); k++ )
                    myContainers[k].updateElements();
          etc.
          }
     public void fooOperation()
          {
          if ( blah ) etc.
          if ( blah ) etc.
          }
     }

Doc 15, Composite Slide # 4
A Better Idea - Program to an interface



class Window
     {
     GUIWidgets[] myWidgets;
     WidgetContainer[] myContainers;
     
     public void update()
          {
          if ( myWidgets != null )
               for ( int k = 0; k < myWidgets.length(); k++ )
                    myWidgets[k].update();
          if ( myContainers != null )
               for ( int k = 0; k < myContainers.length(); k++ )
                    myContainers[k].updateElements();
          etc.
          }
     }

Doc 15, Composite Slide # 5
The Composite Pattern - Version B




Component implements default behavior for widgets when possible

Button, Menu, etc overrides Component methods when needed

WidgetContainer will have to overrides all widgetOperations

class WidgetContainer
     {
     Component[] myComponents;
     
     public void update()
          {
          if ( myComponents != null )
               for ( int k = 0; k < myComponents.length(); k++ )
                    myComponents[k].update();
          }
     }



Doc 15, Composite Slide # 6

Issue: WidgetContainer Operations

WidgetContainer operations tend to relate to adding, deleting and managing widgets

Should the WidgetContainer operations be declared in Component?

Pro - Transparency

Declaring them in the Component gives all subclasses the same interface

All subclasses can be treated alike. (?)


Con - Safety

Declaring them in WidgetContainer is safer

Adding or removing widgets to non-WidgetContainers is an error

What should be the proper response to added a TextArea to a button? throw an exception?

One out is to check the type of the object before using a WidgetContainer operation


Doc 15, Composite Slide # 7

Explicit Parent References


Aid in traversing the structure
class WidgetContainer
     {
     Component[] myComponents;
     
     public void update()
          {
          if ( myComponents != null )
               for ( int k = 0; k < myComponents.length(); k++ )
                    myComponents[k].update();
          }
     public add( Component aComponent )
          {
          myComponents.append( aComponent );
          aComponent.setParent( this );
          }
     }
     
class Button extends Component
     {
     private Component parent;
     public void setParent( Component myParent)
          {
          parent = myParent;
          }
     
     etc.
     }

Doc 15, Composite Slide # 8
More Issues

Should Component implement a list of Components?

The button etc. have a useless data member

Child Ordering is important in some cases

Who should delete components -

If there is no garbage collection Container is best bet



Applicability


Use Composite pattern when


Doc 15, Composite Slide # 9

Java Use of Composite - AWT Widgets





Doc 15, Composite Slide # 10
Specialized Java Containers


visitors since 12-Mar-98