12.07.2015 Views

A Practical Introduction to Data Structures and Algorithm Analysis

A Practical Introduction to Data Structures and Algorithm Analysis

A Practical Introduction to Data Structures and Algorithm Analysis

SHOW MORE
SHOW LESS
  • No tags were found...

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Sec. 1.3 Design Patterns 151.3.3 CompositeThere are two fundamental approaches <strong>to</strong> dealing with the relationship betweena collection of actions <strong>and</strong> a hierarchy of object types. First consider the typicalprocedural approach. Say we have a base class for page layout entities, with asubclass hierarchy <strong>to</strong> define specific subtypes (page, columns, rows, figures, characters,etc.). And say there are actions <strong>to</strong> be performed on a collection of suchobjects (such as rendering the objects <strong>to</strong> the screen). The procedural design approachis for each action <strong>to</strong> be implemented as a method that takes as a parametera pointer <strong>to</strong> the base class type. Each such method will traverse through the collectionof objects, visiting each object in turn. Each method contains something like acase statement that defines the details of the action for each subclass in the collection(e.g., page, column, row, character). We can cut the code down some by usingthe visi<strong>to</strong>r design pattern so that we only need <strong>to</strong> write the traversal once, <strong>and</strong> thenwrite a visi<strong>to</strong>r subroutine for each action that might be applied <strong>to</strong> the collection ofobjects. But each such visi<strong>to</strong>r subroutine must still contain logic for dealing witheach of the possible subclasses.In our page composition application, there are only a few activities that wewould like <strong>to</strong> perform on the page representation. We might render the objects infull detail. Or we might want a “rough draft” rendering that prints only the boundingboxes of the objects. If we come up with a new activity <strong>to</strong> apply <strong>to</strong> the collectionof objects, we do not need <strong>to</strong> change any of the code that implements the existingactivities. But adding new activities won’t happen often for this application. Incontrast, there could be many object types, <strong>and</strong> we might frequently add new objecttypes <strong>to</strong> our implementation. Unfortunately, adding a new object type requiresthat we modify each activity, <strong>and</strong> the subroutines implementing the activities getrather long case statements <strong>to</strong> distinguish the behavior of the many subclasses.An alternative design is <strong>to</strong> have each object subclass in the hierarchy embodythe action for each of the various activities that might be performed. Each subclasswill have code <strong>to</strong> perform each activity (such as full rendering or bounding boxrendering). Then, if we wish <strong>to</strong> apply the activity <strong>to</strong> the collection, we simply callthe first object in the collection <strong>and</strong> specify the action (as a method call on tha<strong>to</strong>bject). In the case of our page layout <strong>and</strong> its hierarchical collection of objects,those objects that contain other objects (such as a row objects that contains letters)will call the appropriate method for each child. If we want <strong>to</strong> add a new activitywith this organization, we have <strong>to</strong> change the code for every subclass. But this isrelatively rare for our text compositing application. In contrast, adding a new objectin<strong>to</strong> the subclass hierarchy (which for this application is far more likely than addinga new rendering function) is easy. Adding a new subclass does not require changing

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!