now*_*wox 3 python design-patterns visitor-pattern
我使用了这里给出的访客示例,我们有这个:
.------------------------.
| Flower |
+------------------------+
| +accept(visitor) |
| +pollinate(pollinator) |
| +eat(eater) |
'------------------------'
Run Code Online (Sandbox Code Playgroud)
我们还有可以是 a 的aBug和a ,以及可以是一朵花的 a 。BeepollinateFlowerPredatoreat
使用访问者模式我可以这样写:
bee = Bee()
fly = Fly()
worm = Worm()
# Using the visitor pattern:
for flower in flowerGen(10):
for object in [bee, fly, worm]:
flower.accept(object)
Run Code Online (Sandbox Code Playgroud)
但代码在没有访问者的情况下仍然具有可读性和功能性:
# Without visitor pattern
for flower in flowerGen(10):
for object in [bee, fly, worm]:
object.visit(flower)
Run Code Online (Sandbox Code Playgroud)
问题是,此示例中的访问者模式有哪些优点?
您链接到的文章非常清楚地说明了为什么您想要使用访问者模式:当您无法更改对象时,因为它们来自第三方:
\n\n\n\n\n假设您有一个固定的主类层次结构;也许它来自另一个供应商,您可以\xe2\x80\x99t 更改该层次结构。但是,您的意图是您\xe2\x80\x99d 喜欢向该层次结构添加新的多态方法,这意味着通常您\xe2\x80\x99d 必须向基类接口添加一些内容。所以困境是你需要向基类添加方法,但你不能\xe2\x80\x99接触基类。你如何解决这个问题?
\n
当然,如果您可以为蜜蜂、苍蝇和蠕虫添加一种visit方法,那就没问题了。但是,当您不能时,使用访问者模式是下一个最佳选择。
请注意,在文章中,关系是相反的;您无法更改Flower层次结构:
\n\n\nRun Code Online (Sandbox Code Playgroud)\n# The Flower hierarchy cannot be changed:\n
但该类确实通过以下方法支持访问者调度模式visit:
class Flower(object):\n def accept(self, visitor):\n visitor.visit(self)\nRun Code Online (Sandbox Code Playgroud)\n\n该实施可能要复杂得多;该示例已被简化为此处的visitor.visit()一个简单调用,但实际上,真正的访问者模式在此阶段可以并且确实可以执行更多操作。
例如,可能存在包含多个子组件的复合类。然后,该accept()方法将进一步委托给这些子元素,然后accept根据需要调用它们。与花卉主题保持一致,也许有菊花或大丽花类,一些游客会吃射线成分,而其他人则想访问眼睛中的成分来授粉。由复合对象将每个访问者单独引导至这些部分。
如果您正在寻找特定的示例,请查看 module ast,它提供了一个NodeVisitor类,该类应该被子类化以添加方法,以便您自定义传入的 AST 树的处理方式。我曾多次使用特定的NodeTransformer子类来改变 Python 代码的工作方式。这里,访问者模式用于有效地过滤掉较大层次结构中的某些类型,从而极大地简化了 AST 处理代码,而无需更改任何 AST 节点类本身。
| 归档时间: |
|
| 查看次数: |
1681 次 |
| 最近记录: |