Skip to Content.
Sympa Menu

gang-of-4-patterns - Re: [gang-of-4-patterns] Visitor Pattern

gang-of-4-patterns AT lists.cs.illinois.edu

Subject: Design Patterns discussion

List archive

Re: [gang-of-4-patterns] Visitor Pattern


Chronological Thread 
  • From: Lívio Cipriano <lcipriano AT iol.pt>
  • To: gang-of-4-patterns AT cs.uiuc.edu
  • Subject: Re: [gang-of-4-patterns] Visitor Pattern
  • Date: Sun, 20 Aug 2006 11:34:24 +0100
  • List-archive: <http://lists.cs.uiuc.edu/pipermail/gang-of-4-patterns>
  • List-id: Design Patterns discussion <gang-of-4-patterns.cs.uiuc.edu>

Hi Roman,

Thanks for your answer.

In fact I considered the Iterator pattern although, I recognize, very
briefly,
because the code example was C++ using templates. Following your advice, I'll
look into those patterns again. Anyaway, I think the code you give will do.


Regards

Lívio Cipriano

----- Original Message -----
#
lcipriano AT iol.pt
/ 2006-08-19 11:30:35 +0100:
> ----- Original Message -----
>
> > #
> > lcipriano AT iol.pt
> > / 2006-08-19 10:48:13 +0100:
> > > I would like to find a pattern, maybe using the Visitor one, that can
> > > be used to traversal a tree.
> >
> > What is your question?
>
> The original Visitor pattern only addresses the "application" of the
> Visitor to one Node (in a tree structure). Of course that was only an
> example, cause the basic utility of this pattern is to add operations to a
> set of related Classes.

The GoF book discusses using iterators for the traversal on p. 336
("Visiting across class hierarchies"), and has example code on
p. 338 and 341 which puts the traversal responsibility in the tree
structure (nonleaf elements call accept() on their children).

The three possible places to put the traversal responsibility (the
visitor, the composite, an iterator) are discussed on p. 339 ("Who
is responsible for traversing the object structure?")

> My problem is that I've a tree structure, I've Visitores and I need to
> traversal the tree applying the Visitores, so I'm looking for an example
> how to do it. Some idea?

class visitor(object):
def visitComponent(self, node):
for child in node.getChildren():
child.accept(self)

or:

class component(object):
def accept(self, visitor):
for child in self.children:
child.accept(visitor)
visitor.visitComponent(self)

or:

class component(object):
def __iter__(self):
return iterator(self.children)

class iterator(object):
def __init__(self, nodes):
self.index = 0
self.nodes = nodes
def __iter__(self):
return self
def next(self):
if self.index >= len(self.nodes):
raise StopIteration
self.index = self.index + 1
return self.nodes[self.index]

Which is appropriate for you depends on which parts of your software
vary.

If all your visitors can work with a single traversal method,
you can put the traversal in the composite's accept(). It makes for
clean, uniform, single-purpose code, unfortunately inflexible.

If the traversal method varies with the visitor then it's better to
put the traversal in the visitor. Visitors that work around an
inappropriate traversal method need to maintain more state, which
makes them more complicated (plus the memory requirements).
The traversal code may clutter the visitor and/or cause redundance.

Finally, the iterator approach frees the visitor from the traversal
responsibility, sometimes making it possible to reduce the visitor
to (basically) a set of callbacks. OTOH it may obscure the code
a bit.

Iterators may present a problem in staticly typed languages, but see
eg. http://www.boost.org/doc/html/variant.html




Archive powered by MHonArc 2.6.16.

Top of Page