Visitor definition: an operation that acts on each object in a certain object group. It allows you to define new operations that act on these objects without changing them themselves.
In Java, the Visitor pattern actually separates elements in the collection structure and the behavior of operating on these elements.
Why use Visitor mode
Java Collection (including Vector and Hashtable) is the technology we use most frequently, but Collection seems to be a large black dyeing vat. Once objects with various distinctive types are put in and then taken out, these types disappear. Then we must use If to judge, such as:
The code copy is as follows:
Iterator iterator = collection.iterator()
while (iterator.hasNext()) {
Object o = iterator.next();
if (o instanceof Collection)
messyPrintCollection((Collection)o);
else if (o instanceof String)
System.out.println("'"+o.toString()+"'");
else if (o instanceof Float)
System.out.println(o.toString()+"f");
else
System.out.println(o.toString());
}
In the above example, we used instanceof to determine the type of o.
Obviously, the disadvantages of doing this If else if code is cumbersome, we can solve it using Visitor mode.
How to use Visitor mode
For the above example, we design an interface visitor visitor:
The code copy is as follows:
public interface Visitor
{
public void visitCollection(Collection collection);
public void visitString(String string);
public void visitFloat(Float float);
}
In this interface, put the types of classes we think that Collection is possible.
With visitors, we need to be visited. The visitor is each element of our collection. We need to define an interface that can be accessed for these Elements (the access and access are interactive, only visitors are accessed. If the user expresses that he does not welcome him, the visitor will not be able to visit).
We define this interface as Visitable, which is to define an Accept operation, that is, make each element of the Collection accessible.
The code copy is as follows:
public interface Visitable{
public void accept(Visitor visitor);
}
OK, with two interfaces, we need to define their specific implementation (Concrete class):
The code copy is as follows:
public class ConcreteElement implements Visitable
{
private String value;
public ConcreteElement(String string) {
value = string;
}
//Define the specific content of accept Here is a very simple sentence to call public void accept(Visitor visitor) {
visitor.visitString(this);
}
}
Let’s take a look at the visitor’s Concrete implementation:
The code copy is as follows:
public class ConcreteVisitor implements Visitor
{
//In this method, we implement successful access to the elements of the Collection public void visitCollection(Collection collection) {
Iterator iterator = collection.iterator()
while (iterator.hasNext()) {
Object o = iterator.next();
if (o instance of Visitable)
((Visitable)o).accept(this);
}
public void visitString(String string) {
System.out.println("'"+string+"'");
}
public void visitFloat(Float float) {
System.out.println(float.toString()+"f");
}
}
In the above visitCollection we implement access to each element of the Collection, using only one judgment statement, just to determine whether it is accessible.
At this point, we have completed the basic architecture of the Visitor model.
Prerequisites for using Visitor mode
The object type in the object group structure is rarely changed, that is, the identity type of the visitor is rarely changed, such as the type in Visitor above is rarely changed, if new operations are needed, such as in the example above, we In addition to the ConcreteElement specific implementation, the new ConcreteElement2 ConcreteElement3 is also needed.
It can be seen that there is a prerequisite for using the Visitor mode. In the two interfaces Visitor and Visitable, make sure that the Visitor changes very little, and the change is Visitable, so it is most convenient to use Visitor.
If Visitor also changes frequently, that is, the object types in the object group often change, the general suggestion is that it is better to define operations one by one in these object classes, but Java's Reflect technology solves this problem.