Visitor mode
Definition: separate the operations that act on each element in a data structure and package them into independent classes, so that they can add new operations that act on these elements without changing the data structure, and provide a variety of access methods for each element in the data structure. It separates the operation of data from the data structure.
Visitor mode is an object behavior mode. Its main advantages are as follows:
1. The extended type is good. It can add new functions to the elements in the object structure without modifying the elements in the object structure
2. Good reusability. Visitors can define the general functions of the whole object structure, so as to improve the reuse degree of the system
3. Good flexibility. Visitor mode decouples the data structure from the operations acting on the structure, so that the operation set can evolve relatively freely without affecting the data structure of the system
4. Comply with the principle of single responsibility. Visitor mode encapsulates the relevant behaviors to form a visitor, so that the function of each visitor is relatively single
The main disadvantages of the Visitor mode are as follows:
1. Adding new element classes is difficult. In the visitor mode, every time a new element class is added, the corresponding specific operation must be added to each person's specific access class, which violates the "opening and closing principle"
2. Destroy the package. In the visitor pattern, concrete elements publish details to visitors, which destroys the encapsulation of objects
3. It violates the principle of dependency inversion. The visitor pattern relies on concrete classes instead of abstract classes
Pattern structure and code examples
The visitor pattern contains the following main roles
1. Abstract Visitor role: define an interface for accessing concrete elements. Each concrete element corresponds to an access operation visit(). The parameter type in the operation identifies the accessed concrete elements
2. Concrete visitor role: it implements each access operation declared in the abstract visitor role and determines what the visitor should do when accessing an element
3. Abstract Element role: declare an interface containing the accept operation accept(), and the accepted visitor object is used as the parameter of the accept() method
4. Concrete element role: implement the accept() operation provided by the abstract element role. Its method body is usually visitor.visit(this). In addition, the specific element may also contain relevant operations of its own business logic
5. Object Structure role: it is a container containing element roles and provides methods for visitor objects to traverse all elements in the container. It is usually implemented by aggregate classes such as List, Set and Map.
1. Abstract visitor
public interface Visitor { abstract public void Visit(Element element); }
2. Specific visitors
public class CompensationVisitor implements Visitor { @Override public void Visit(Element element) { // TODO Auto-generated method stub Employee employee = ((Employee) element); System.out.println( employee.getName() + "'s Compensation is " + (employee.getDegree() * employee.getVacationDays() * 10)); } }
3. Abstract element
public interface Element { abstract public void Accept(Visitor visitor); }
4. Specific elements
public class CompensationVisitor implements Visitor { @Override public void Visit(Element element) { // TODO Auto-generated method stub Employee employee = ((Employee) element); System.out.println( employee.getName() + "'s Compensation is " + (employee.getDegree() * employee.getVacationDays() * 10)); } }
5. Object structure
public class ObjectStructure { private HashMap<String, Employee> employees; public ObjectStructure() { employees = new HashMap(); } public void Attach(Employee employee) { employees.put(employee.getName(), employee); } public void Detach(Employee employee) { employees.remove(employee); } public Employee getEmployee(String name) { return employees.get(name); } public void Accept(Visitor visitor) { for (Employee e : employees.values()) { e.Accept(visitor); } } }