GoF Definition: Represent an operation to be performed on the elements of an object structure. The visitor pattern lets you define a new operation without changing the classes of the elements on which it operates.
This pattern helps us to add new functionalities to an existing object structure in such a way that the old structure remains unaffected by these changes. So, we can follow the open/close principle here (i.e., extension allowed but modification disallowed for entities like class, function, modules, etc.).
Consider a taxi booking scenario. The taxi arrives at our defined location for the pickup. Once we enter into it, the visiting taxi takes control of the transportation. It can choose a different way toward our destination and we may or may not have any prior knowledge of that way.
This pattern is very useful when plugging happens into public APIs. Clients can then perform operations on a class with a visiting class without modifying the source.
Plugging into public APIs is a common example. Then a client can perform his desired operations without modifying the actual code (with a visiting class).
Here we have illustrated a simple example to represent a visitor pattern. In order to do this, we have implemented a new class hierarchy (IVisitor hierarchy) and we have implemented the algorithms there. So, any modification/update operation in the IOriginalInterface hierarchy can be done through this new class hierarchy without affecting the code in the IOriginalInterface hierarchy.
In the following example, we want to modify the initial integer value in MyClass (which implements the Interface IOriginalInterface) through the visitor pattern. Note that we are not touching the code in IOriginalInterface. We are separating functionality implementations (i.e., algorithms) from the class hierarchy where these algorithms operate.
High-level structure of the parts of the program is as follows:
package visitor.pattern.demo;
interface IOriginalInterface
{
void accept(IVisitor visitor);
}
class MyClass implements IOriginalInterface
{
//Initial or default value
private int myInt = 5;
public int getMyInt()
{
return myInt;
}
public void setMyInt(int myInt)
{
this.myInt = myInt;
}
@Override
public void accept(IVisitor visitor)
{
System.out.println("Initial value of the integer :"+ myInt);
visitor.visit(this);
System.out.println(" Value of the integer now :"+ myInt);
}
}
interface IVisitor
{
void visit(MyClass myClassElement);
}
class Visitor implements IVisitor
{
@Override
public void visit(MyClass myClassElement)
{
System.out.println("Visitor is trying to change the integer value");
myClassElement.setMyInt(100);
System.out.println("Exiting from Visitor- visit");
}
}
class VisitorPatternEx
{
public static void main(String[] args)
{
System.out.println("***Visitor Pattern Demo*** ");
IVisitor v = new Visitor();
MyClass myClass = new MyClass();
myClass.accept(v);
}
}
3.146.35.72