加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 为什么我们通过调用Acceptor.accept()而不是Visitor.vis

发布时间:2020-12-14 05:48:07 所属栏目:Java 来源:网络整理
导读:在Wikipedia sample和GoF书中,访问者模式的使用是通过在某个接受者上调用accept方法来启动的.但为什么会这样呢?为什么我们不能开始使用所需的acceptor作为参数调用visit方法?我们仍然可以使访问者行为依赖于两种类型 – 访问者和接受者(双重调度) – 并且
在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

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读