Java Reference
In-Depth Information
that represents the page. At another time, we might wish to print a listing of all the
nodes for debugging purposes.
We could write a separate traversal function for each such activity that we in-
tend to perform on the tree. A better approach would be to write a generic traversal
function, and pass in the activity to be performed at each node. This organization
constitutes the visitor design pattern. The visitor design pattern is used in Sec-
tions 5.2 (tree traversal) and 11.3 (graph traversal).
1.3.3
Composite
There are two fundamental approaches to dealing with the relationship between
a collection of actions and a hierarchy of object types. First consider the typical
procedural approach. Say we have a base class for page layout entities, with a sub-
class hierarchy to define specific subtypes (page, columns, rows, figures, charac-
ters, etc.). And say there are actions to be performed on a collection of such objects
(such as rendering the objects to the screen). The procedural design approach is for
each action to be implemented as a method that takes as a parameter a pointer to
the base class type. Each action such method will traverse through the collection
of objects, visiting each object in turn. Each action method contains something
like a switch 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
using the visitor design pattern so that we only need to write the traversal once, and
then write a visitor subroutine for each action that might be applied to the collec-
tion of objects. But each such visitor subroutine must still contain logic for dealing
with each of the possible subclasses.
In our page composition application, there are only a few activities that we
would like to perform on the page representation. We might render the objects in
full detail. Or we might want a “rough draft” rendering that prints only the bound-
ing boxes of the objects. If we come up with a new activity to apply to the collection
of objects, we do not need to change any of the code that implements the existing
activities. But adding new activities won't happen often for this application. In
contrast, there could be many object types, and we might frequently add new ob-
ject types to our implementation. Unfortunately, adding a new object type requires
that we modify each activity, and the subroutines implementing the activities get
rather long switch statements to distinguish the behavior of the many subclasses.
An alternative design is to have each object subclass in the hierarchy embody
the action for each of the various activities that might be performed. Each subclass
will have code to perform each activity (such as full rendering or bounding box
rendering). Then, if we wish to apply the activity to the collection, we simply call
the first object in the collection and specify the action (as a method call on that
object). In the case of our page layout and its hierarchical collection of objects,
those objects that contain other objects (such as a row objects that contains letters)
Search WWH ::




Custom Search