|
Data Structures and Algorithms
with Object-Oriented Design Patterns in Python |
As shown in Program
,
the Visitor class also includes the property isDone.
The isDone property
calls the getIsDone accessor
to determine whether a visitor has finished its work.
That is, the getIsDone method returns the bool value
True if the visitor ``is done.''
The idea is this: Sometimes a visitor does not need to visit all the objects in a container. That is, in some cases, the visitor may be finished its task after having visited only a some of the objects. The isDone property can be used by the container to terminate the accept method early like this:
class SomeContainer(Container):
def accept(self, visitor):
for i in self:
if visitor.isDone:
return
visitor.visit(i)
# ...
To illustrate the usefulness of isDone, consider a visitor which visits the objects in a container with the purpose of finding the first object that matches a given target object. Having found the first matching object in the container, the visitor is done and does not need to visit any more contained objects.
The following code fragment defines a visitor which finds the first object in the container that matches a given object.
class MatchingVisitor(Visitor):
def __init__(self, target):
self.target = target
self.found = None
def visit(self, obj):
if not self.isDone and obj == target:
self.found = obj
def isDone(self):
return found not is None:
The __init__ method of the MatchingVisitor visitor takes an Object instance that is the target of the search. That is, we wish to find an object in a container that matches the target. For each object the MatchingVisitor visitor visits, it compares that object with the target and makes found point at that object if it matches. Clearly, the MatchingVisitor visitor is done when the found pointer is non-zero.
Suppose we have a container c that is an instance of a concrete container class, SomeContainer, derived from the abstract Container class; and an object x that is an instance of a concrete object class, SomeObject, derived from the abstract Object class. Then, we can call use the MatchingVisitor visitor as follows:
c = SomeContainer() x = SomeObject() // ... c.accept(MatchingVisitor(x))