java – 为什么我们通过调用Acceptor.accept()而不是Visitor.visit()来启动Visitor?

前端之家收集整理的这篇文章主要介绍了java – 为什么我们通过调用Acceptor.accept()而不是Visitor.visit()来启动Visitor?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在Wikipedia sample和GoF书中,访问者模式的使用是通过在某个接受者上调用accept方法来启动的.但为什么会这样呢?为什么我们不能开始使用所需的acceptor作为参数调用visit方法?我们仍然可以使访问者行为依赖于两种类型 – 访问者和接受者(双重调度) – 并且我们可以消除冗余呼叫(在我看来).

这是用于说明这一点的示例代码

public interface Visitor {
    void visit(AcceptorA acceptor);
    void visit(AcceptorB acceptor);
}

//
// Visitor which sings
// 
class SingingVisitor implements Visitor {
    public void visit(AcceptorA acceptor) {
        System.out.println("sing A");
    }

    public void visit(AcceptorB acceptor) {
        System.out.println("sing B");
    }
}


//
// Visitor which talks
// 
class TalkingVisitor implements Visitor {
    public void visit(AcceptorA acceptor) {
        System.out.println("talk A");
    }

    public void visit(AcceptorB acceptor) {
        System.out.println("talk B");
    }
}

//
// Acceptor subclasses
// 
class AcceptorA implements BaseAcceptor {
}

class AcceptorB implements BaseAcceptor {
}

//
// Launcher class
// 
class VisitorMain {
    public static void main(String[] args) {
        Visitor v = new TalkingVisitor();
        AcceptorA a = new AcceptorA();
        AcceptorB b = new AcceptorB();

        v.visit(a);
        v.visit(b);
        v = new SingingVisitor();
        v.visit(a);
        v.visit(b);
    }
}

解决方法

考虑:
class House implements HouseAcceptor {
    HouseAcceptor kitchen;
    HouseAcceptor livingRoom;

    void accept(HouseVisitor visitor) {
        visitor.visit(this);
        kitchen.accept(visitor);
        livingRoom.accept(visitor);
    }
}

class Kitchen implements HouseAcceptor {
    void accept(HouseVisitor visitor) {
        visitor.visit(this);
    }
}

class LivingRoom implements HouseAcceptor {
    void accept(HouseVisitor visitor) {
         visitor.visit(this);
    }
}

class SpeakingHouseVisitor implements HouseVisitor {
    void visit(HouseAcceptor acceptor) {
        System.out.println("Inside a HouseAcceptor");
    }

    void visit(House acceptor) {
        System.out.println("Inside a House");
    }

    void visit(Kitchen acceptor) {
        System.out.println("Inside a Kitchen");
    }

    void visit(LivingRoom acceptor) {
        System.out.println("Inside a LivingRoom");
    }
}

...
HouseAcceptor acceptor = new House();
HouseVisitor visitor = new SpeakingHouseVisitor();

...
// Doing it your way
visitor.visit(acceptor);
// Output: Inside a HouseAcceptor

// Doing it the right way
acceptor.accept(visitor);
// Output:
// Inside a House
// Inside a Kitchen
// Inside a LivingRoom

请注意,如果按照自己的方式执行,接受器的运行时类型将没有区别:将使用静态类型.通过执行双重调度,您可以确保使用两种运行时类型.

猜你在找的Java相关文章