23 Design Modes (16)-Visitor mode
Definition: Encapsulates certain operations that act on elements of a data structure, and it can define new operations that act on these elements without altering the data structure.
Type: Behavior class mode
Class Diagram:
The visitor pattern may be one of the most complex patterns in the behavioral class pattern, but this cannot be a reason why we do not have to master it.
Let's start with a simple example of the code below
Class A {
public void Method1 () {
System.out.println ("I am a");
}
public void Method2 (b b) {
B.showa (this);
}
}
Class B {
public void ShowA (a a) {
A.method1 ();
}
}
We mainly look at the difference between method Method1 and method Method2 in Class A, the method method1 is simple, which is to print out a phrase "I am a"; the method method2 a little more complex, uses Class B as a parameter, and invokes the Showa method of Class B.
Then look at the Showa method of Class B, the Showa method uses Class A as a parameter, and then call the Method1 method of Class A, you can see that the Method2 method around to go around, nothing is called a method1 method of its own, it should also run the result should be "I am a", After the analysis, let's run through the two methods and look at the results of the operation:
public class Test {
public static void Main (string[] args) {
A = new A ();
A.method1 ();
A.METHOD2 (New B ());
}
}
The result of the operation is:
I'm a.
I'm a.
Understanding This example, you understand the visitor pattern of 90%, in the example, for Class A, Class B is a visitor. But this example is not all of the visitor pattern, although intuitive, but its scalability is poor, let's say the common implementation of the visitor pattern, through the class diagram can be seen in the visitor pattern, mainly includes the following roles:
Abstract Visitor: An abstract class or interface that declares which elements a visitor can access, specifically to the program in which the parameters in the Visit method define which objects can be accessed.
Visitor: Implements the method that the abstract visitor declares, which affects what the visitor does and does when he accesses a class.
Abstract element class: An interface or abstract class that declares which type of visitor access to accept is defined by the parameters in the Accept method. Abstract elements generally have two types of methods, part of their own business logic, and the other is what kind of visitors are allowed to receive access.
Element class: Implementing the Accept method declared by the abstract element class, usually visitor.visit (this), has basically formed a stereotype.
Structure object: A container for an element that typically contains a container that accommodates multiple different classes and interfaces, such as list, Set, map, and so on, which is rarely abstracted from this role in a project.
Common code implementations for visitor patterns
Abstract class Element {
public abstract void Accept (Ivisitor visitor);
public abstract void dosomething ();
}
Interface Ivisitor {
public void Visit (ConcreteElement1 el1);
public void Visit (ConcreteElement2 el2);
}
Class ConcreteElement1 extends Element {
public void dosomething () {
System.out.println ("This is element 1");
}
public void Accept (Ivisitor visitor) {
Visitor.visit (this);
}
}
Class ConcreteElement2 extends Element {
public void dosomething () {
System.out.println ("This is Element 2");
}
public void Accept (Ivisitor visitor) {
Visitor.visit (this);
}
}
Class Visitor implements Ivisitor {
public void Visit (ConcreteElement1 el1) {
El1.dosomething ();
}
public void Visit (ConcreteElement2 el2) {
El2.dosomething ();
}
}
Class Objectstruture {
public static list<element> GetList () {
list<element> list = new arraylist<element> ();
Random ran = new random ();
for (int i=0; i<10; i++) {
int a = ran.nextint (100);
if (a>50) {
List.add (New ConcreteElement1 ());
}else{
List.add (New ConcreteElement2 ());
}
}
return list;
}
}
public class Client {
public static void Main (string[] args) {
list<element> list = Objectstruture.getlist ();
for (Element e:list) {
E.accept (New Visitor ());
}
}
}
Advantages of the visitor pattern
Conforms to the single duty principle: In any scenario where the visitor pattern is applied, the action that needs to be encapsulated in the visitor in the element class must be an operation that is not related to the element class itself and is variable, while using the visitor pattern on the one hand conforms to the principle of single responsibility and, on the other hand, because the encapsulated operation is usually variable, , we can realize the expansion of the changing part without changing the element class itself.
Good extensibility: element classes can be extended to different operations by accepting different audiences.
The appropriate scenario for the visitor pattern
If there are some operations in an object that are irrelevant (or weaker) to this object, you can use the visitor pattern to encapsulate these actions to the visitor in order to avoid polluting the object.
If there is a similar operation in a set of objects, you can encapsulate the repeated actions in the visitor in order to avoid the occurrence of a large number of duplicated code.
However, the visitor pattern is not perfect, it also has a fatal flaw: it is difficult to add new element classes. The code for the visitor pattern can be seen in the visitor class, where each element class has its corresponding processing method, that is, each additional element class needs to modify the visitor class (also including access to the