所以,我刚刚在阅读关于访问者模式的内容时发现访问者和元素之间的来回操作非常奇怪!
基本上我们调用元素,将它传递给访问者,然后元素将自己传递给访问者。然后访问者操作元素。为什么?这感觉很不必要。我称之为“来回疯狂”。
因此,访问者的意图是在需要在所有元素中实现相同操作时将元素与其操作解耦。这样做是因为如果我们需要使用新操作扩展元素,我们不希望进入所有那些类并修改已经稳定的代码。所以我们在这里遵循开放/封闭原则。
为什么会有这种来回操作,如果没有这个会失去什么?
例如,我编写了这个代码以考虑到这个目的,但跳过了访问者模式的交互困扰。基本上,我有可以跳跃和吃东西的动物。我想将这些动作从对象中解耦,所以我将这些操作移到访问者中。吃和跳跃会增加动物的健康值(我知道,这是一个非常愚蠢的例子……)
public interface AnimalAction { // Abstract Visitor
public void visit(Dog dog);
public void visit(Cat cat);
}
public class EatVisitor implements AnimalAction { // ConcreteVisitor
@Override
public void visit(Dog dog) {
// Eating increases the dog health by 100
dog.increaseHealth(100);
}
@Override
public void visit(Cat cat) {
// Eating increases the cat health by 50
cat.increaseHealth(50);
}
}
public class JumpVisitor implements AnimalAction { // ConcreteVisitor
public void visit(Dog dog) {
// Jumping increases the dog health by 10
dog.increaseHealth(10);
}
public void visit(Cat cat) {
// Jumping increases the cat health by 20
cat.increaseHealth(20);
}
}
public class Cat { // ConcreteElement
private int health;
public Cat() {
this.health = 50;
}
public void increaseHealth(int healthIncrement) {
this.health += healthIncrement;
}
public int getHealth() {
return health;
}
}
public class Dog { // ConcreteElement
private int health;
public Dog() {
this.health = 10;
}
public void increaseHealth(int healthIncrement) {
this.health += healthIncrement;
}
public int getHealth() {
return health;
}
}
public class Main {
public static void main(String[] args) {
AnimalAction jumpAction = new JumpVisitor();
AnimalAction eatAction = new EatVisitor();
Dog dog = new Dog();
Cat cat = new Cat();
jumpAction.visit(dog); // NOTE HERE. NOT DOING THE BACK AND FORTH MADNESS.
eatAction.visit(dog);
System.out.println(dog.getHealth());
jumpAction.visit(cat);
eatAction.visit(cat);
System.out.println(cat.getHealth());
}
}
1+1=2
表示为Equals(Plus(Literal(1), Literal(1)), Literal(2))
)。显然,Equals
/Plus
等是通用的,因为表达式不必是简单文字,现在考虑如何编写一个访问者来计算此表达式......然后编写一些代码来解析表达式的文本并对其进行评估,现在您在编译时没有任何具体已知类。 - GACy20