Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is Visitor Mode?

2025-01-14 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly introduces "what is the Visitor pattern". In the daily operation, I believe that many people have doubts about what the Visitor pattern is. The editor has consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful for you to answer the doubts about "what is Visitor Mode"! Next, please follow the editor to study!

The visitor mode focuses on the word visitor. When it comes to interviews, we are bound to think of news interviews in which two people are sitting face to face. From the literal meaning: in fact, the interviewee (a public figure) treats the interviewer (reporter) as an outsider and doesn't want you to move casually. What do you want? I'll give it to you when I'm done (call your method).

01 what is Visitor Mode?

The visitor pattern is defined as follows, which means defining a new operation without changing the data structure in advance.

Encapsulates operations that act on elements in a data structure, which can define new operations that act on those elements without changing the data structure.

But in practical applications, I have found that some examples are not the case. In some cases, there are no stable data structures, but stable algorithms. In the sense of the tree, the visitor pattern is to fix the unchanged and open up the changed.

Let's take an example in life to talk about: a scientist was interviewed by a reporter. We all know that when scientists are interviewed, there must be procedural restrictions, and it is impossible for you to ask casually. Let's assume that the process is: first ask scientists about their school experience, then talk about your work experience, and finally talk about your scientific research achievements. So what is fixed in this process? What is fixed is the process of giving an interview. What has changed? What has changed is that different journalists may ask different questions according to their school experience.

According to our previous understanding, the visitor pattern is actually to fix the same things and open up the changes. Well, we can abstract the matter of scientists being interviewed in this way.

First of all, we need to have a Visitor class that defines some things that can be done externally (by journalists) (asking questions about school experience, work experience, and scientific achievements).

Public interface Visitor {public void askSchoolExperience (String name); public void askWorkExperience (String name); public void askScienceAchievement (String name);}

Then declare a XinhuaVisitor class to implement the Visitor class, which means that a reporter (visitor) from Xinhua wants to visit the scientist.

Public class XinhuaVisitor implements Visitor {@ Override public void askSchoolExperience (String name) {System.out.printf ("excuse me% s: what is the greatest achievement in school? \ n ", name);} @ Override public void askWorkExperience (String name) {System.out.printf (" excuse me% s: what is the most unforgettable thing at work? \ n ", name);} @ Override public void askScienceAchievement (String name) {System.out.printf (" excuse me% s: what is the greatest scientific research achievement? " , name);}}

Then declare a Scientist class, indicating that it is a scientist. Scientists receive requests from journalists (visitors) through an accept () method and store them. Scientists have defined an interview method that sets the flow of interviews to a dead end. I will only let you ask questions when I teach you what to ask.

Public class Scientist {private Visitor visitor; private String name; private Scientist () {} public Scientist (String name) {this.name = name;} public void accept (Visitor visitor) {this.visitor = visitor;} public void interview () {System.out.println ("- access starts -") System.out.println ("start talking about school experience -"); visitor.askSchoolExperience (name); System.out.println ("- start talking about work experience -"); visitor.askWorkExperience (name); System.out.println ("- start talking about scientific research achievements -"); visitor.askScienceAchievement (name);}}

Finally, we declare a scenario class Client to simulate the interview process.

Public class Client {public static void main (String [] args) {Scientist yang = new Scientist ("Yang Zhenning"); yang.accept (new XinhuaVisitor ()); yang.interview ();}}

The result of the operation is:

-at the beginning of the interview-start talking about school experience-ask Yang Zhenning: what is the greatest achievement in school? -start talking about work experience-ask Yang Zhenning: what is the most unforgettable opinion on work? -start talking about scientific research achievements-ask Yang Zhenning: what is the greatest scientific research achievement?

Seeing here, people have a more perceptual understanding of the nature of the visitor pattern (fixing the constant and opening up the changing). In this example, the constant is the interview process, and the change is that you can ask different questions.

In general, the class structure of the visitor pattern is shown in the following figure:

Visitor Visitor Interface. The visitor interface defines what visitors can do. This requires you to analyze what is mutable, abstract the mutable content into a visitor interface, and open it up. In fact, the information of the interviewee is passed through the parameters of the visitor.

Specific visitors to ConcreteVisitor. A specific visitor defines the implementation of a specific type of visitor. For Xinhua News Agency reporters, they are more concerned about Yang Zhenning's scientific achievements, so when they ask questions, they are more inclined to dig for the results. But for Youth Daily reporters, their readers are teenagers, and they are more concerned about Yang Zhenning's spirit in his study and work.

Element specific elements. This refers to the specific accessed class, and in our case to the Scientist class. In general, we will provide an accept () method that receives visitor parameters, which will be equivalent to accepting its sample application. But this method is not necessary, as long as you can get the visitor object, you can pass this parameter whatever you want.

For the visitor pattern, nothing is more important than the Visitor, ConcreteVisitor, and Element classes. Visitor and ConcreteVisitor define what the visitor can do, and the parameters of the visitor are passed to the visitor through parameters. Element gets the visited object in a variety of ways, often through the accept () method, but this is not absolute.

It is important to note that the focus of our study of design patterns is to understand the relationship between classes and the messages they convey. It doesn't matter how it is passed, through the accept () method, or through the constructor.

02 practical application of visitor pattern

Earlier, we used a living example to help you understand the visitor pattern. I believe you should have a perceptual understanding of the visitor pattern. In order to return to the programming practice itself, so that everyone can have a better practical understanding of the visitor pattern. Next we will talk about the application of the visitor pattern in the open source framework from the perspective of software programming.

File tree traversal

We are naturally aware of the file manipulation in JDK. If there is a file operation, there will naturally be a folder traversal operation, that is, access to all files or folders under a folder. Just imagine, what do we need to do if we want to print out the names of all the files and folders under a folder?

In fact, it is very simple to do a tree traversal, and then print out the name!

Yes, this is the right answer!

What if I want to count all the files and folders?

Then go through it again, and then use a counter to keep adding one!

Yes, that's the right answer, too!

But did you find that in both processes, we have the same operation: traversing the file tree. Whether printing the file name or calculating the file tree, we need to traverse the file tree. No matter which process, what we want in the end is to access the file.

Remember what we said about the nature of design patterns? The essence of design patterns is to find out what remains the same, then find out what has changed, and then find the appropriate data structure (design pattern) to carry the change.

In this example, the constant is the traversal of the file tree, and what changes are the different access operations to the file. It is clear that the visitor pattern is more suitable for hosting this change. We can fix this immutable thing (traversal of the file tree) and open up the changed things (the specific operation of the file). JDK traverses the file tree using the Visitor pattern.

A FileVisitor interface is declared in JDK, defining the actions that traversers can do.

Public interface FileVisitor {FileVisitResult preVisitDirectory (T dir, BasicFileAttributes attrs); FileVisitResult visitFile (T file, BasicFileAttributes attrs) throws IOException; FileVisitResult visitFileFailed (T file, IOException exc) throws IOException; FileVisitResult postVisitDirectory (T dir, IOException exc) throws IOException;}

The visitFile () method defined in FileVisitor is actually an access to a file. The information of the visited person (file) is passed through the first parameter file. In this way, the trader can access the contents of the file.

SimpleFileVisitor is the implementation of the FileVisitor interface, this class only does a simple parameter check, and there is no too much logic.

Public class SimpleFileVisitor implements FileVisitor {@ Override public FileVisitResult preVisitDirectory (T dir, BasicFileAttributes attrs) throws IOException {Objects.requireNonNull (dir); Objects.requireNonNull (attrs); return FileVisitResult.CONTINUE;} @ Override public FileVisitResult visitFile (T file, BasicFileAttributes attrs) throws IOException {Objects.requireNonNull (file); Objects.requireNonNull (attrs); return FileVisitResult.CONTINUE } / /.... Other omissions}

The FileVisitor class and SimpleFileVisitor class correspond to the Visitor and ConcreteVisitor classes in the UML class diagram. The Element element actually corresponds to the Files class in JDK.

Traversing the file tree in the Files file is achieved through the walkFileTree () method. The traversal of the tree is realized in the walkFileTree () method. When traversing to the file, the traversal method is called through the visitFile method of the visitor class, and the traversed file is passed to the trader, so as to achieve the purpose of separating changes.

ASM modified bytecode

ASM is the bytecode enhancement technology of Java, which uses the visitor pattern, which is mainly used to modify the bytecode. The three classes related to this in ASM are: ClassReader, ClassVisitor, and ClassWriter.

The ClassReader class is equivalent to the Element element in the visitor schema. It reads the byte array or class file into memory and represents it as the data structure of the tree. This class defines an accept method to interact with visitor.

ClassVisitor is the equivalent of an abstract visitor interface. After the ClassReader object is created, you need to call the accept () method, passing in a ClassVisitor object. Different visit () methods in the ClassVisitor object are called at different times of the ClassReader to modify the bytecode.

ClassWriter is the implementation class of ClassVisitor, which is responsible for outputting the modified bytecode as a byte array.

For scenarios such as ASM, the bytecode specification is very strict and stable, and it can be problematic if you change it casually. However, we need to modify the bytecode dynamically in order to achieve some purposes. In this case, the designers of ASM adopt the visitor pattern to isolate the changed parts and fix the unchanged parts, thus achieving the purpose of flexible expansion.

03 how should we use it?

From the above examples, we can generally understand the usage scenario of the visitor pattern: something that is more stable (data structure or algorithm), does not want to be changed directly but wants to expand the function, so it is suitable to use the visitor pattern.

When it comes to the definition of the visitor pattern usage scenario, we will feel that the template method pattern is very similar to the definition of this usage scenario. But there are still some differences between them. Between the change of the visitor pattern and the non-change (that is, the visitor and the visited), they are only a simple inclusive relationship, while the change and non-change of the template method pattern is an inheritance relationship. But they do have similarities, that is, they all encapsulate fixed things and open up changing things.

The advantage of the visitor pattern is obvious, that is, it isolates the changed things, fixes the same things, and makes the whole more maintainable and scalable. But it also brings some disadvantages of common design patterns, such as:

The class structure becomes complex. In the past, we used to have a simple invocation relationship, but now it is an inheritance and composition relationship between multiple classes. To a certain extent, it improves the requirements for developers and increases the cost of research and development.

The change of the interviewee becomes more difficult. For example, in our example of the scientist interview above, if the scientist interview wants to add a new section, then the Scientist class needs to be modified, and both the Visitor class and the XinhuaVisitor class need to be modified.

There are many advantages, but also so many disadvantages, so how should we judge whether to use the visitor pattern in practice? The general principle is to make full use of the strengths and avoid weaknesses, that is, when the scenario takes full advantage of the advantages of the visitor pattern and avoids the disadvantages of the visitor pattern, it is the best time to use the visitor pattern.

Although using the visitor pattern will make it more difficult to change the interviewee, if the interviewee is stable and basically will not change, then this disadvantage will not be removed. In the case of ASM, for example, the element is ClassReader, which stores the bytecode structure. The bytecode structure does not change easily, so the disadvantage of "the change of the interviewee becomes more difficult" does not exist.

The disadvantage of "class structure becomes complex" needs to be viewed according to the complexity of the business at that time. If the business was simple and did not change much, then the use of design patterns was completely redundant. But if the business is very complicated at that time and we still make changes in the same class, it is very likely that there will be a big problem. At this point, you need to use design patterns to host complex business structures.

At this point, the study of "what is the Visitor pattern" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report