带有内部树的访客设计模式

Posted

技术标签:

【中文标题】带有内部树的访客设计模式【英文标题】:Visitor Design pattern with inner tree 【发布时间】:2014-11-14 19:31:40 【问题描述】:

我在理解与树相关的访问者设计模式时遇到了一些麻烦。据我了解,树本身需要一个接受访问者界面参数的接受方法。当您遍历树时,visitor.visit() 方法需要访问树中的每个节点和数据。

假设树需要是一个私有内部类。

我要挂断的部分是树的父类需要有一个方法,该方法需要访问树的所有节点,并且还具有访问者界面作为参数。

我对 Java 还是很陌生,如果有任何方向,我将不胜感激。

【问题讨论】:

看复合设计模式,也许能帮到你 【参考方案1】:

虽然访问者模式似乎经常以遍历不同运行时类型的节点树的形式呈现,但重要的是要了解访问者模式的基本特征是双重分派。因此,访问者模式同样适用于您希望根据对象的类自定义行为但不知道该类究竟是什么的静态情况。

例子:

interface Shape 
    public void accept(ShapeVisitor v);


interface ShapeVisitor 
    public void visit(Circle c);
    public void visit(Square s);
    public void visit(Shape h);


class Circle implements Shape 
    double radius;
    public void accept(ShapeVisitor v) 
        v.visit(this);  // The correct overload is chosen at compile time
    


class Square implements Shape 
    double edge;
    public void accept(ShapeVisitor v) 
        v.visit(this);  // The correct overload is chosen at compile time
    


class AreaVisitor implements ShapeVisitor 
    double area;

    public void visit(Circle c) 
        area = Math.PI * c.radius * c.radius;
    

    public void visit(Square s) 
        area = s.edge * s.edge;
    

    public void visit(Shape h) 
        // A Shape implementation other than Square or Circle
        throw new RuntimeException(
                "I don't know how to compute the area of a " + h.getClass());
    

AreaVisitor 可以计算它理解的任何形状的面积,即使形状类本身没有提供任何方法,即使特定类型的形状不是静态已知的。 (看妈,没有树!)

如果你碰巧有一棵树,Visitor 的各种visit() 方法可以选择访问哪些子节点,被访问的节点可以在其accept() 方法中做出决定。哪个更合适取决于访问者界面的性质和被访问的类型。在任何一种情况下,如果访问者打算以某种方式遍历树,则通常通过向根节点询问访问者对象accept() 来启动该过程。

如果碰巧有一个对象代表整个树(根节点除外),那么我刚才描述的设计选择也必须在该级别进行。您可以通过将访问者传递给容器对象的某个方法来开始访问。该方法当然可以将访问者传递给树根节点的accept() 方法。但是,如果容器恰好属于为访问者设计的一个类,那么它也可以选择将自己传递给访问者的 visit() 方法中的适当一个。

但请注意,访问者模式取决于访问者要区分的类型(示例中为 CircleSquareShape)以在访问者范围内访问接口及其所有具体实现。您可以使用它来访问其他类型的对象,但它们必须是为访问者设计的类型之一的子类型。

【讨论】:

以上是关于带有内部树的访客设计模式的主要内容,如果未能解决你的问题,请参考以下文章

访客设计模式 - 返回类型

javascript 访客行为设计模式

如何创建默认的“访客”会话,以便设计助手 current_user 显示我的访客用户?

以访客至上的网页设计

访问复合模式 Java 的叶子

带有页面树的内部链接的通量域