I found many people implement Visitor design pattern in python as follows:
class Node(object):
def accept(self, visitor):
visitor.visit(self)
# some code ...
class Visitor(object):
def visit(self, node):
# invoke corresponding method according to the type of node
# ...
node = Node()
visitor = Vistor()
node.accept(visitor)
For Java or other C-like static language, they use accept()
to implement multi-dispatch. Because the visit()
method choose specific override method only by the static type of reference. For example:
public class MyVisitor implements IVisitor {
void visit(AddNode node);
void visit(Node node);
}
Node node = AddNode(); // AddNode is derived from Node
new MyVisitor().visit(root);
The visitor will invoke the method for Node
rather than AddNode
. Thus, accept()
is necessary to get the "real" type of instance as follow:
public class AddNode extends Node implements IVisitable{
void accept(IVisitor visitor) {
visitor.visit(this)
}
}
However, the type could be directly extract from instance in python. The Visitor
could be implement as follow:
class Visitor(object):
def visit(self, node):
classname = node.__class__.__name__
_visit = getattr(self, '_visit_'+classname)
_visit(node)
def _visit_AddNode(self, node):
pass
Then, we could visit the node by using visit()
directly
node = AddNode()
visitor = Visitor()
visitor.visit(node)
This way is more natural and simpler. Why do people still implement Visitor design pattern in python by accept()
?
Aucun commentaire:
Enregistrer un commentaire