Visitor
pattern allows you to add new operations or methods to a set of classes without modifying the structure of those classes.
This pattern is especially useful when you want to centralise a particular operation on an object without extending the object Or without modifying the object.
UML diagram from wikipedia:
Code snippet:
import java.util.HashMap;
interface Visitable{
void accept(Visitor visitor);
}
interface Visitor{
void logGameStatistics(Chess chess);
void logGameStatistics(Checkers checkers);
void logGameStatistics(Ludo ludo);
}
class GameVisitor implements Visitor{
public void logGameStatistics(Chess chess){
System.out.println("Logging Chess statistics: Game Completion duration, number of moves etc..");
}
public void logGameStatistics(Checkers checkers){
System.out.println("Logging Checkers statistics: Game Completion duration, remaining coins of loser");
}
public void logGameStatistics(Ludo ludo){
System.out.println("Logging Ludo statistics: Game Completion duration, remaining coins of loser");
}
}
abstract class Game{
// Add game related attributes and methods here
public Game(){
}
public void getNextMove(){};
public void makeNextMove(){}
public abstract String getName();
}
class Chess extends Game implements Visitable{
public String getName(){
return Chess.class.getName();
}
public void accept(Visitor visitor){
visitor.logGameStatistics(this);
}
}
class Checkers extends Game implements Visitable{
public String getName(){
return Checkers.class.getName();
}
public void accept(Visitor visitor){
visitor.logGameStatistics(this);
}
}
class Ludo extends Game implements Visitable{
public String getName(){
return Ludo.class.getName();
}
public void accept(Visitor visitor){
visitor.logGameStatistics(this);
}
}
public class VisitorPattern{
public static void main(String args[]){
Visitor visitor = new GameVisitor();
Visitable games[] = { new Chess(),new Checkers(), new Ludo()};
for (Visitable v : games){
v.accept(visitor);
}
}
}
Explanation:
Visitable
(Element
) is an interface and this interface method has to be added to a set of classes.Visitor
is an interface, which contains methods to perform an operation on Visitable
elements.GameVisitor
is a class, which implements Visitor
interface ( ConcreteVisitor
).Visitable
element accept Visitor
and invoke a relevant method of Visitor
interface.Game
as Element
and concrete games like Chess,Checkers and Ludo
as ConcreteElements
.In above example, Chess, Checkers and Ludo
are three different games ( and Visitable
classes). On one fine day, I have encountered with a scenario to log statistics of each game. So without modifying individual class to implement statistics functionality, you can centralise that responsibility in GameVisitor
class, which does the trick for you without modifying the structure of each game.
output:
Logging Chess statistics: Game Completion duration, number of moves etc..
Logging Checkers statistics: Game Completion duration, remaining coins of loser
Logging Ludo statistics: Game Completion duration, remaining coins of loser
Use cases/Applicability:
Additional references: