So, I was just reading about the Visitor pattern and I found the back and forth between the Visitor and the Elements very strange!
Basically we call the element, we pass it a visitor and then the element passes itself to the visitor. AND THEN the visitor operates the element. What? Why? It feels so unnecessary. I call it the "back and forth madness".
So, the intention of the Visitor is to decouple the Elements from their actions when the same actions need to be implemented across all the elements. This is done because in case we need to extend our Elements with new actions, we don't want to go into all those classes and modify code that is already stable. So we're following the Open/Closed principle here.
I made this code that keeps that purpose in mind but skips the interaction madness of the visitor pattern. Basically I have Animals that jump and eat. I wanted to decouple those actions from the objects, so I move the actions to Visitors. Eating and jumping increases the animal health (I know, this is a very silly example...)
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());
}
}
So yeha, I'm keeping the main idea of the Visitor pattern without the back and forth madness. Is this OK?
Aucun commentaire:
Enregistrer un commentaire