the*_*lse 5 python design-patterns visitor-pattern python-2.7
请考虑以下之前,我去我的关于特定问题(例如)代码visitor pattern中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)
Run Code Online (Sandbox Code Playgroud)
当我运行它时,它迭代地遍历所有节点类并返回以下内容:
Node
NodeA
NodeA_A
NodeA_A_A
NodeA_B
NodeB
Run Code Online (Sandbox Code Playgroud)
这一切都很好,但现在我的问题.你可能已经注意到每个check-method返回一个布尔值(假设这是一个复杂的方法).
在上面的示例中,类中的每个check-method都Node返回True除外NodeA_A_A.我想在访问期间以某种方式存储它,所以我可以使所有基类失败.
这很难解释让我说明一下:
NodeA_A_A返回False,那么我想失败NodeA_A, NodeA and Node.不管这些类返回什么.NodeB返回False,那么我想失败Node.不管其他类返回什么.因此,如果child-class某个地方失败(检查方法返回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
Run Code Online (Sandbox Code Playgroud)
输出如下:
-------------------
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
Run Code Online (Sandbox Code Playgroud)