访客模式(从下到上) 在下面的代码中,请考虑下面的(例子)代码,在代码< > Python < /C> >:< /P> class Node: def __init__(self): self.children = [] def add(self, node): self.children.append(node) def check(self): print("Node") return True def accept(self, visitor): visitor.visit(self) class NodeA(Node): def check(self): print("NodeA") return True class NodeB(Node): def check(self): print("NodeB") return True class NodeA_A(NodeA): def check(self): print("NodeA_A") return True class NodeA_B(NodeA): def check(self): print("NodeA_B") return True class NodeA_A_A(NodeA_A): def check(self): print("NodeA_A_A") return False class NodeRunner: def visit(self, node): node.check() if len(node.children) > 0: for child in node.children: child.accept(self) if __name__ == "__main__": n = Node() n1 = NodeA() n2 = NodeB() n11 = NodeA_A() n12 = NodeA_B() n111 = NodeA_A_A() n.add(n1) n.add(n2) n1.add(n11) n1.add(n12) n11.add(n111) v = NodeRunner() v.visit(n)
当我运行它时,它会迭代遍历所有节点类,并返回以下内容:访客模式(从下到上) 在下面的代码中,请考虑下面的(例子)代码,在代码< > Python < /C> >:< /P> class Node: def __init__(self): self.children = [] def add(self, node): self.children.append(node) def check(self): print("Node") return True def accept(self, visitor): visitor.visit(self) class NodeA(Node): def check(self): print("NodeA") return True class NodeB(Node): def check(self): print("NodeB") return True class NodeA_A(NodeA): def check(self): print("NodeA_A") return True class NodeA_B(NodeA): def check(self): print("NodeA_B") return True class NodeA_A_A(NodeA_A): def check(self): print("NodeA_A_A") return False class NodeRunner: def visit(self, node): node.check() if len(node.children) > 0: for child in node.children: child.accept(self) if __name__ == "__main__": n = Node() n1 = NodeA() n2 = NodeB() n11 = NodeA_A() n12 = NodeA_B() n111 = NodeA_A_A() n.add(n1) n.add(n2) n1.add(n11) n1.add(n12) n11.add(n111) v = NodeRunner() v.visit(n),python,design-patterns,python-2.7,visitor-pattern,Python,Design Patterns,Python 2.7,Visitor Pattern,当我运行它时,它会迭代遍历所有节点类,并返回以下内容: Node NodeA NodeA_A NodeA_A_A NodeA_B NodeB 这一切都很好,但现在我的问题是。您可能已经注意到,每个check-方法都返回一个布尔值(假设这实际上是一个复杂的方法) 在上面的示例中,节点类中的每个检查-方法返回真,除了节点A。我想在访问期间以某种方式存储它,这样我就可以使所有基类失败 这很难解释让我举例说明: 如果NodeA\u A\u A返回False,则我希望失败NodeA\u A、NodeA
Node
NodeA
NodeA_A
NodeA_A_A
NodeA_B
NodeB
这一切都很好,但现在我的问题是。您可能已经注意到,每个check
-方法都返回一个布尔值(假设这实际上是一个复杂的方法)
在上面的示例中,节点
类中的每个检查
-方法返回真
,除了节点A
。我想在访问期间以某种方式存储它,这样我就可以使所有基类失败
这很难解释让我举例说明:
- 如果
返回NodeA\u A\u A
,则我希望失败False
。不管这些类返回什么NodeA\u A、NodeA和Node
- 如果
返回NodeB
,则我希望节点False
失败。不管其他类返回什么
子类
在某个地方失败(check方法返回False
),我希望它的所有基类都失败
有人有什么想法吗 看来,您要求的不是访问者模式,而是如何实现深度优先搜索算法。以下是我对你的问题的解决方案:
class Node:
def __init__(self):
self.children = []
def add(self, node):
self.children.append(node)
def check(self):
print("Node")
return True
def accept(self, visitor):
return visitor.visit(self)
class NodeA(Node):
def check(self):
print("NodeA")
return True
class NodeB(Node):
def check(self):
print("NodeB")
return True
class NodeA_A(NodeA):
def check(self):
print("NodeA_A")
return True
class NodeA_B(NodeA):
def check(self):
print("NodeA_B")
return True
class NodeA_A_A(NodeA_A):
def check(self):
print("NodeA_A_A")
return False
class NodeRunner:
def visit(self, node):
ret = True
# visit all children
for child in node.children:
v = child.accept(self)
if not v and ret: # if some child not accepted, then we think that the parent node should also not be accepted
ret = False
# check the node
if not node.check():
ret = False
return ret
if __name__ == "__main__":
n = Node()
n1 = NodeA()
n2 = NodeB()
n11 = NodeA_A()
n12 = NodeA_B()
n111 = NodeA_A_A()
n.add(n1)
n.add(n2)
n1.add(n11)
n1.add(n12)
n11.add(n111)
v = NodeRunner()
print v.visit(n)
我使用访问者模式访问所有节点。 一个访问者访问并运行所有节点,另一个访问者将结果冒泡出来。 代码和输出如下所示:
class Node(object):
def __init__(self):
self.children = []
self.result = None
def add(self, node):
self.children.append(node)
def check(self):
self.result = True
print "Node: result:%s" % self.result
return self.result
def accept(self, visitor):
visitor.visit(self)
class Node_A(Node):
def __init__(self):
super(Node_A, self).__init__()
def check(self):
self.result = True
print "Node_A: result:%s" % self.result
return self.result
class Node_A_A(Node_A):
def __init__(self):
super(Node_A_A, self).__init__()
def check(self):
self.result = True
print "Node_A_A: result:%s" % self.result
return self.result
class Node_A_B(Node_A):
def __init__(self):
super(Node_A_B, self).__init__()
def check(self):
self.result = True
print "Node_A_B: result:%s" % self.result
return self.result
class Node_A_A_A(Node_A_A):
def __init__(self):
super(Node_A_A_A, self).__init__()
def check(self):
self.result = True
print "Node_A_A_A: result:%s" % self.result
return self.result
class Node_A_A_B(Node_A_A):
def __init__(self):
super(Node_A_A_B, self).__init__()
def check(self):
self.result = False
print "Node_A_A_B: result:%s" % self.result
return self.result
class Node_A_B_A(Node_A_B):
def __init__(self):
super(Node_A_B_A, self).__init__()
def check(self):
self.result = True
print "Node_A_B_A: result:%s" % self.result
return self.result
class NodeRunner:
def visit(self, node):
if len(node.children) > 0:
for child in node.children:
child.accept(self)
node.check()
class NodeChecker:
def visit(self, node):
results = []
if len(node.children) > 0:
for child in node.children:
child.accept(self)
results.append(child.result)
node.result = all(results)
if __name__ == "__main__":
node = Node()
node_a = Node_A()
node_a_a = Node_A_A()
node_a_b = Node_A_B()
node_a_a_a = Node_A_A_A()
node_a_a_b = Node_A_A_B()
node_a_b_a = Node_A_B_A()
node.add(node_a)
node_a.add(node_a_a)
node_a_a.add(node_a_a_a)
node_a_a.add(node_a_a_b)
node_a.add(node_a_b)
node_a_b.add(node_a_b_a)
print("-------------------")
nVisitor = NodeRunner()
nVisitor.visit(node)
print("-------------------")
nVisitor = NodeChecker()
nVisitor.visit(node)
print("-------------------")
print "node_a_a_a: result: %s" % node_a_a_a.result
print "node_a_a_b: result: %s" % node_a_a_b.result
print "node_a_a: result: %s" % node_a_a.result
print "node_a_b_a: result: %s" % node_a_b_a.result
print "node_a_b: result: %s" % node_a_b.result
print "node_a: result: %s" % node_a.result
print "node: result: %s" % node.result
-------------------
Node_A_A_A: result:True
Node_A_A_B: result:False
Node_A_A: result:True
Node_A_B_A: result:True
Node_A_B: result:True
Node_A: result:True
Node: result:True
-------------------
-------------------
node_a_a_a: result: True
node_a_a_b: result: False
node_a_a: result: False
node_a_b_a: result: True
node_a_b: result: True
node_a: result: False
node: result: False
输出如下所示:
class Node(object):
def __init__(self):
self.children = []
self.result = None
def add(self, node):
self.children.append(node)
def check(self):
self.result = True
print "Node: result:%s" % self.result
return self.result
def accept(self, visitor):
visitor.visit(self)
class Node_A(Node):
def __init__(self):
super(Node_A, self).__init__()
def check(self):
self.result = True
print "Node_A: result:%s" % self.result
return self.result
class Node_A_A(Node_A):
def __init__(self):
super(Node_A_A, self).__init__()
def check(self):
self.result = True
print "Node_A_A: result:%s" % self.result
return self.result
class Node_A_B(Node_A):
def __init__(self):
super(Node_A_B, self).__init__()
def check(self):
self.result = True
print "Node_A_B: result:%s" % self.result
return self.result
class Node_A_A_A(Node_A_A):
def __init__(self):
super(Node_A_A_A, self).__init__()
def check(self):
self.result = True
print "Node_A_A_A: result:%s" % self.result
return self.result
class Node_A_A_B(Node_A_A):
def __init__(self):
super(Node_A_A_B, self).__init__()
def check(self):
self.result = False
print "Node_A_A_B: result:%s" % self.result
return self.result
class Node_A_B_A(Node_A_B):
def __init__(self):
super(Node_A_B_A, self).__init__()
def check(self):
self.result = True
print "Node_A_B_A: result:%s" % self.result
return self.result
class NodeRunner:
def visit(self, node):
if len(node.children) > 0:
for child in node.children:
child.accept(self)
node.check()
class NodeChecker:
def visit(self, node):
results = []
if len(node.children) > 0:
for child in node.children:
child.accept(self)
results.append(child.result)
node.result = all(results)
if __name__ == "__main__":
node = Node()
node_a = Node_A()
node_a_a = Node_A_A()
node_a_b = Node_A_B()
node_a_a_a = Node_A_A_A()
node_a_a_b = Node_A_A_B()
node_a_b_a = Node_A_B_A()
node.add(node_a)
node_a.add(node_a_a)
node_a_a.add(node_a_a_a)
node_a_a.add(node_a_a_b)
node_a.add(node_a_b)
node_a_b.add(node_a_b_a)
print("-------------------")
nVisitor = NodeRunner()
nVisitor.visit(node)
print("-------------------")
nVisitor = NodeChecker()
nVisitor.visit(node)
print("-------------------")
print "node_a_a_a: result: %s" % node_a_a_a.result
print "node_a_a_b: result: %s" % node_a_a_b.result
print "node_a_a: result: %s" % node_a_a.result
print "node_a_b_a: result: %s" % node_a_b_a.result
print "node_a_b: result: %s" % node_a_b.result
print "node_a: result: %s" % node_a.result
print "node: result: %s" % node.result
-------------------
Node_A_A_A: result:True
Node_A_A_B: result:False
Node_A_A: result:True
Node_A_B_A: result:True
Node_A_B: result:True
Node_A: result:True
Node: result:True
-------------------
-------------------
node_a_a_a: result: True
node_a_a_b: result: False
node_a_a: result: False
node_a_b_a: result: True
node_a_b: result: True
node_a: result: False
node: result: False
你所说的
基类是什么意思?它是子类
还是父类
还是真正的类?您期望的输出是什么?@User所说的“基本类”是指继承的类!e、 NodeA继承自Node,Node是它的基类。它真的与Visitor/Composite模式有关吗?好的,您有了复合结构,并使用Visitor添加了操作。但对我来说,你真正需要的是额外的状态模式,使行为依赖于某种“共享”状态。我一直认为访问者模式是穷人版本的多重分派(特别是双重分派)。您使用的不是Java或C#,而是Python,它是动态的,支持多方法(通过或)。那么,你为什么使用访客?(顺便说一句,我也很高兴听到其他人对这个问题的看法。我想不出一个好的理由在Python中使用访问者,但我想知道是否有一个好的用例。)嗨,这真的不是我想要的。您的代码甚至不会访问所有节点。我希望子节点设置其基类的结果,这应该一直进行。@theAlse因此您希望访问所有节点,并且当某个子节点未能通过检查时,父节点的结果也将为false。我说得对吗?