【发布时间】:2013-09-10 13:22:06
【问题描述】:
在我回答关于visitor pattern in python 的具体问题之前,请考虑下面的(示例)代码:
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)
当我运行它时,它会迭代地遍历所有节点类并返回以下内容:
Node
NodeA
NodeA_A
NodeA_A_A
NodeA_B
NodeB
这一切都很好,但现在是我的问题。您可能已经注意到每个check-method 都返回一个布尔值(假设这实际上是一个复杂的方法)。
在上面的示例中,Node 类中的每个check 方法都返回True,但NodeA_A_A 除外。我想在访问期间以某种方式存储它,这样我就可以使所有基类失败。
这很难解释,我来说明一下:
- 如果
NodeA_A_A返回False,那么我想失败NodeA_A, NodeA and Node。不管这些类返回什么。 - 如果
NodeB返回False,那么我想失败Node。不管其他类返回什么。
因此,如果child-class 在某处失败(检查方法返回False),我希望它的所有基类都失败。
有人有什么想法吗?
【问题讨论】:
-
base classes是什么意思?是children还是parents还是真正的班级? -
你的预期输出是什么?
-
@User 'Bases Classes' 我的意思是被继承的类!例如NodeA 继承自 Node,Node 是它的基类。
-
它真的与访问者/复合模式有关吗?好的,您拥有复合结构,并使用访问者添加操作。但对我来说,您真正需要的另外是使行为依赖于某些“共享”状态的状态模式。
-
我一直将访问者模式视为穷人版本的多次调度(特别是双重调度)。您使用的不是Java 或C#,而是Python,它是动态的并且支持多方法(通过multimethods 或PEAK-rules)。那么,为什么要使用访问者呢? (PS 我也很高兴听到其他人对该主题的看法。我想不出在 Python 中使用访问者的充分理由,但我想了解是否有一个好的用例。 )
标签: python design-patterns python-2.7 visitor-pattern