Java访客模式2

use*_*398 2 java design-patterns visitor

以下是我用更好的代码示例提出的问题的后续问题:

以下代码使用访问者模式:

class Animal { void accept(Visitor v) { v.visit(this); } }
class Cat extends Animal {}
class Dog extends Animal {}
class Poodle extends Dog {}

interface Visitor {
    public void visit(Animal a);
    public void visit(Cat a);
    public void visit(Dog a);
    public void visit(Poodle a);
}

class TalkVisitor implements Visitor {
    public void visit(Animal a) { System.out.println("?"); }
    public void visit(Cat a) { System.out.println("Meow"); }
    public void visit(Dog a) { System.out.println("bark"); }
    public void visit(Poodle a) { System.out.println("Arf"); }
}    

class WalkVisitor implements Visitor {
    public void visit(Animal a) { System.out.println("?"); }
    public void visit(Cat a) { System.out.println("Sneak"); }
    public void visit(Dog a) { System.out.println("Walk"); }
    public void visit(Poodle a) { System.out.println("Skip"); }
} 

public class Demo{
    public static void main(String []args){
        Animal list[] = { new Cat(), new Dog(), new Poodle() };

        for (Animal a : list)
            a.accept(new TalkVisitor());

        for (Animal a : list)
            a.accept(new WalkVisitor());    
    }
} 
Run Code Online (Sandbox Code Playgroud)

输出是:

?
?
?
?
Run Code Online (Sandbox Code Playgroud)

如何在不添加Animal.accept()中的instanceof开关的情况下修复它?(每次添加新动物类时我都不想维护switch())

Mar*_*nik 6

我认为实现抽象类的访问方法没有意义(在你的情况下是Animal).

在访客中,您始终知道所有可能的子类型.它是一种基本假设(否则你向Visitor接口添加新方法).但您获得了动态实现不同行为的能力.在你的情况下它的谈话和走路.

要付出的代价是在每种具体类型中实施"接受"方法.你试图提供一个更通用的解决方案,并感到困惑:)例如,看看维基百科的描述.

他们在讨论Car的不同部分,但想法是一样的:他们为所有部分实现了一个接受方法.

希望这可以帮助