1. The concept of visitor mode
Encapsulates operations that act on elements in a data structure to define new operations on those elements without changing the data structure.
If you understand this sentence, you don't have to look down. It means you will.
I don't understand, I think it's normal. If you can learn with one sentence, no one will read.A fool like me learns a pattern and then sets its definition.
2. When to use the visitor mode
Visitor mode, all you have to do is separate the data structure from the way you handle it.
It is understandable that there is a tree-like data structure within which there are many ways to manipulate this structure, such as traversing trees, copying trees, searching trees, and so on.
When this data structure meets enough requirements, methods to implement it (such as adding, modifying, deleting nodes) are confused with methods to manipulate it (such as traversal, replication, search, and so on), which can be bloated and difficult to read and maintain.
At this point, you can choose to use the visitor mode to separate the data structure from the operation. Here's what to do.
3. How to Use Visitor Mode
3.1 Disadvantages of not using visitor mode
The disadvantage of not using the visitor mode is that the data structure is bloated and difficult to read and maintain.Not demonstrating the code here shows that I've done a JS Tree control before, and there are about 3,000 lines of code in a tree.js. Just think about how bloated this code file is.
3.2 How to use visitor mode to separate data structures from operations
For example, you can follow the tree structure of the vehicle brand and the car family in the combination mode, after trimming the code, the class diagram is as follows:
The class is described as follows:
Sequence Number | Name | Explain |
1 | Visitor | Visitor Abstract class, which defines access methods to access brands and car systems |
2 | ListVisitor | Traversal operation visitor, achieve the traversal operation of car type tree and car system tree |
3 | CopyVisitor | Copy Operation Visitor, realizing copy operation of car type tree and car system tree |
4 | Element | Interface classes for data structures that can be accessed |
5 | Component | Component Classes in Composite Mode |
6 | Brand | Vehicle Brand Class |
7 | Series | Vehicle System Class |
Visitor, ListVisitor, CopyVisitor represent the visitor class, which can manipulate the data structure.
The remaining Element s, Component s, Brand, Series represent data structure classes that can accept a visitor to access themselves.
Class diagrams aren't intuitive, so here's how visitor patterns are used, using code directly.
3.3 Code Samples
/** * An abstract class of visitors that defines different types of methods for accessing data structures. * Multiple types can be manipulated using method overload. */ public abstract class Visitor { public abstract void visit(Brand brand); public abstract void visit(Series series); } /** * Visitors to traverse operations. * Inherits the visitor's abstract class and implements the abstract method. * Since it is the visitor to the traversal operation, the method mainly implements the traversal business. */ public class ListVisitor extends Visitor { public void visit(Brand brand) { System.out.println(brand.getName() + "Traverse the brand tree."); } public void visit(Series series) { System.out.println(series.getName() + "Traverse the car family tree."); } } /** * Visitor to copy operation. * Inherits the visitor's abstract class and implements the abstract method. * Since it is the visitor to the copy operation, the method mainly implements the copy business. */ public class CopyVisitor extends Visitor { public void visit(Brand brand) { System.out.println(brand.getName() + "Copy the brand tree."); } public void visit(Series series) { System.out.println(series.getName() + "Copy the system tree."); } } //------------------------------------------------------------------- //------------------------------------------------------------------- /** * A data structure that allows a visitor to operate requires that the interface be implemented. * * There is a method declaration in the interface that accepts a visitor Abstract class. */ public interface Element { void accept(Visitor visitor); } /** * Component object */ public abstract class Component implements Element { public String getName() { throw new UnsupportedOperationException(); } public void add(Component component) { throw new UnsupportedOperationException(); } public void remove(Component component) { throw new UnsupportedOperationException(); } } /** * brand */ public class Brand extends Component { private List<Component> series = new ArrayList<Component>(); private String name; public Brand(String name) { this.name = name; } public String getName() { return this.name; } public void add(Component component) { series.add(component); } public void remove(Component component) { series.remove(component); } /** * Key method!Receives a visitor by argument. * The visitor's method is then called to pass itself through parameters to the visitor. */ public void accept(Visitor visitor) { visitor.visit(this); } } /** * Car system */ public class Series extends Component { private String name; public Series(String name) { this.name = name; } public String getName() { return this.name; } /** * Key method!Receives a visitor by argument. * The visitor's method is then called to pass itself through parameters to the visitor. */ public void accept(Visitor visitor) { visitor.visit(this); } }
The above is an implementation of the Visitor pattern, and the following is a Main function to use this pattern:
public class Client { public static void main(String[] args) { // Create Data Structure Brand brand = new Brand("Bence."); Series series1 = new Series("Benz A Department."); Series series2 = new Series("Benz C Department."); Series series3 = new Series("Benz E Department."); brand.add(series1); brand.add(series2); brand.add(series3); // Call the visitor to manipulate the data structure. // When accept on a data structure object is called, a visitor is passed in. // Is equivalent to deciding what to do when invoking the accept method. // The specific operations are encapsulated in the visitor, and the data structure is passed to the visitor as a parameter in the accept. brand.accept(new ListVisitor()); brand.accept(new CopyVisitor()); series1.accept(new ListVisitor()); series1.accept(new CopyVisitor()); } }
4. Summary
If you find the visitor mode very ambiguous, you can mainly look at these points:
public abstract class Visitor { public abstract void visit(Brand brand); public abstract void visit(Series series); }
When defining a visitor, the parameter to the visit method is the data structure.
public interface Element { void accept(Visitor visitor); }
When defining a data structure, this structure must be implemented, that is, an accept method must be implemented in the data structure to receive a specific visitor.
public void accept(Visitor visitor) { visitor.visit(this); }
The method implementation calls the visitor's visit method in accept, passing the data structure itself (this) to the visitor's visit method.
series1.accept(new ListVisitor());
When you want to manipulate the data structure, the visitors you need are passed to the accept method.
The above can be understood as a way to implement the visitor mode, but don't forget that the mindset of the visitor mode is to separate the data structure from the operation method.
Understanding the method of mind first and learning the pattern of enrollment will make sense. This is my experience in learning the visitor pattern.
These are just some of my understanding of the visitor pattern. There are some deficiencies. Please point out that thank you.