【问题标题】:Is there a way to avoid using method for self invoke inside every element in Visitor Pattern?有没有办法避免在访问者模式的每个元素中使用自调用方法?
【发布时间】:2015-05-05 22:24:43
【问题描述】:
interface ICarElementVisitor {
    void visit(Engine engine);
}

interface ICarElement {
    //want to use this
    void accept(ICarElementVisitor visitor); // CarElements have to provide accept().
}

static class Engine implements ICarElement {
    ...
    //want to avoid using this
    public void accept(ICarElementVisitor visitor) {
        visitor.visit(this);
    }
}
...
public void accept(ICarElementVisitor visitor) {
    for (ICarElement elem : elements) {
        elem.accept(visitor);
    }
    visitor.visit(this);
}
    ...
static class CarElementDoVisitor implements ICarElementVisitor {

    public void visit(Engine engine) {
        System.out.println("Starting my engine");
    }

}

有没有办法避免在访问者模式中的每个元素内部使用自调用方法并使用父类的全局方法?或者如果没有instanceof if 或switch,我是否可以传递父对象并知道该对象是什么实例?

【问题讨论】:

  • AFIAK 不在 Java 中。您的编译器需要对访问者方法进行早期绑定,因此它需要知道确切的类型。你可以看到更多关于 Java 如何在编译时选择正确的方法here
  • 为什么要避免这种情况?这是一个多态调用,是访问者模式本质的一部分。 visitor.visit(this) 允许轻松扩展新功能,即,您可以编写新的访客代码,而您永远不必触摸 ICarElement 代码。使用instanceof 意味着对于每种其他类型的访客,您必须为instanceof 添加新检查。我猜你还没有理解访问者解决的问题,因为你提出的问题让问题再次出现。
  • 我不想使用 visitor.visit(this);在我想去的每一堂课中

标签: java design-patterns casting visitor-pattern


【解决方案1】:

我认为您必须这样做才能确保所有ICarElement 中的所有ICarElementVisitor 都有相应的visit() 方法

所以如果你写一个新的ICarElement,比如说IWheel,一年后你不记得所有访问者已经存在,你将不得不实现accept(ICarElementVisitor)方法做visitor.visit(this);这样做编译器会说:“ICarElementVisitor 中没有方法 visit(IWheel)!”所以你将在ICarElementVisitor 接口中添加visit(IWheel),编译器会说“CarElementDoVisitor 没有实现ICarElementVisitor 的所有方法!”并且您将在CarElementDoVisitor 中实现visit(IWheel),因此您一定会避免回归。

我认为这样做的意义在于它并没有什么用处,实际上是一件好事。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-17
    • 2011-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-10
    • 1970-01-01
    相关资源
    最近更新 更多