Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.
Example - Shopping cart
We will implement a shopping cart full of vegetables that we will be able to visit and get its weight (so we can then get the price for it).
interface Visitorable {
int accept(Visitor visitor);
}
interface Visitor {
int getWeight(Apple apple);
int getWeight(Banana banana);
}
class VisitorImpl implements Visitor {
@Override
public int getWeight(Apple apple) {
return apple.getWeight();
}
@Override
public int getWeight(Banana banana) {
return banana.getWeight();
}
}
class Apple implements Visitorable {
private int weight;
public Apple(int weight) {
this.weight = weight;
}
public int getWeight() {
return weight;
}
@Override
public int accept(Visitor visitor) {
return visitor.getWeight(this);
}
}
class Banana implements Visitorable {
private int weight;
public Banana(int weight) {
this.weight = weight;
}
public int getWeight() {
return weight;
}
@Override
public int accept(Visitor visitor) {
return visitor.getWeight(this);
}
}
Now we are going to create apple and banana and visit them in order to get its weight. It is going to return sum equal to 250.
Visitor visitor = new VisitorImpl();
Visitorable[] visitorables = {new Apple(100), new Banana(150)};
Long sum = Arrays
.stream(visitorables)
.collect(Collectors.summarizingInt(it -> it.accept(visitor)))
.getSum();
System.out.println(sum);