gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:53:47 26 4
gpt4 key购买 nike

在维基百科中 sample在 GoF 书中,访问者模式的使用是通过调用某些接受器上的 accept 方法开始的。但是为什么会这样呢?为什么我们不能以所需的接受器作为参数开始调用 visit 方法?我们仍然可以使访问者的行为取决于两种类型——访问者和接受者(双重 dispatch )——并且我们可以消除冗余调用(在我看来)。

下面是示例代码来说明这一点:

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

请注意,如果您按照自己的方式进行操作,接受器的运行时类型不会产生影响:将使用静态类型。通过执行双重分派(dispatch),您可以确保使用两种运行时类型。

关于java - 为什么我们通过调用 Acceptor.accept() 而不是 Visitor.visit() 来启动 Visitor?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8809511/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com