Visitor Mode
In the book "Design pattern: The basis of reusable object-oriented software" in Gof, the visitor pattern is said to represent an operation that acts on elements in an object's structure. It allows you to define new actions that act on these elements without changing the class of each element. The visitor pattern frees up the coupling between the data structure and the operations acting on the structure, allowing the set of operations to evolve relatively freely. The purpose of this pattern is to separate the processing from the data structure. The visitor pattern makes it easy to add new operations because adding new operations means adding a new visitor. The visitor pattern concentrates the behavior on a visitor object. Now let's talk about the project that I've been through before.
is a Windows shell-based project that stores a lot of shell items in a container, and defines the operations for items, since the project has been extended late and the operations for items need to be expanded later on, and now it's Defines an action class in which a collection is defined that stores items and expands the corresponding action method in the action class. Now think about it if using the visitor pattern is also possible, because the items collection is fixed, and when you need to extend the operation of the collection, you only need to add the corresponding visitor.
UML Class Diagram
Visitor (visitor): declares a visit operation for each class concreteelement in the object structure. The name and characteristics of the operation identify the class that sent the visit request to that visitor. This allows the visitor to determine the specific class of elements being accessed. This allows the visitor to access it directly through the element's specific interface.
Concretevisitor (Specific visitor): Implements each action declared by visitor. Each operation implements part of the algorithm, and the algorithm fragment is the class that corresponds to the object in the structure. Concretevisitor provides the context for the algorithm and stores its local state. This state often accumulates results in the process of traversing the structure.
Element: Defines an accept operation that takes a visitor as a parameter.
Concreteelement (specific Element): Implements the accept operation, which takes a visitor as a parameter.
Objectstructure (object structure): The ability to enumerate its elements while providing a high-level interface to allow the visitor to access its elements.
Use occasions
- An object structure contains many classes of objects, and they have different interfaces, and you want to implement some operations that depend on their specific classes for these objects;
- You need to do many different and unrelated operations on objects in an object structure, and you want to avoid classes that let these actions "pollute" those objects. Visitor allows you to centralize related operations in a single class;
- When the object structure is shared by many applications, use visitor mode to have each app contain only the actions that need to be used;
- Classes that define the structure of an object rarely change, but it is often necessary to define new operations on this structure. Changing the object structure class requires redefining the interface to all visitors, which can take a significant cost. If the object structure classes often change, it might be better to define them in these classes.
Code implementation
1#include <iostream>2#include <vector>3 using namespacestd;4 5 classConcreteelementa;6 classConcreteelementb;7 8 classVisitor9 {Ten Public: One Virtual voidVisitconcreteelementa (concreteelementa *pelementa) =0; A Virtual voidVISITCONCRETEELEMENTB (concreteelementb *pelementb) =0; - }; - the classConcreteVisitor1: PublicVisitor - { - Public: - voidVisitconcreteelementa (Concreteelementa *Pelementa); + voidVISITCONCRETEELEMENTB (CONCRETEELEMENTB *pelementb); - }; + A voidConcretevisitor1::visitconcreteelementa (Concreteelementa *Pelementa) at { - //now, based on the Pelementa, you can manipulate the element in the Concreteelementa - } - - voidCONCRETEVISITOR1::VISITCONCRETEELEMENTB (CONCRETEELEMENTB *pelementb) - { in //now, based on the PELEMENTB, you can manipulate the element in the CONCRETEELEMENTB - } to + classConcreteVisitor2: PublicVisitor - { the Public: * voidVisitconcreteelementa (Concreteelementa *Pelementa); $ voidVISITCONCRETEELEMENTB (CONCRETEELEMENTB *pelementb);Panax Notoginseng }; - the voidConcretevisitor2::visitconcreteelementa (Concreteelementa *Pelementa) + { A // ... the } + - voidCONCRETEVISITOR2::VISITCONCRETEELEMENTB (CONCRETEELEMENTB *pelementb) $ { $ // ... - } - the //Element Object - classElementWuyi { the Public: - Virtual voidAccept (Visitor *pvisitor) =0; Wu }; - About classConcreteelementa: PublicElement $ { - Public: - voidAccept (Visitor *pvisitor); - }; A + voidConcreteelementa::accept (Visitor *pvisitor) the { -Pvisitor->visitconcreteelementa ( This); $ } the the classCONCRETEELEMENTB: PublicElement the { the Public: - voidAccept (Visitor *pvisitor); in }; the the voidConcreteelementb::accept (Visitor *pvisitor) About { thePVISITOR->VISITCONCRETEELEMENTB ( This); the } the + //The Objectstructure class, which can enumerate its elements, can provide a high-level interface to allow visitors to access its elements - classobjectstructure the {Bayi Public: the voidAttach (Element *pelement); the voidDetach (Element *pelement); - voidAccept (Visitor *pvisitor); - the Private: theVector<element *>elements; the }; the - voidObjectstructure::attach (Element *pelement) the { the Elements.push_back (pelement); the }94 the voidObjectstructure::D Etach (Element *pelement) the { theVector<element *>::iterator it =Find (Elements.begin (), Elements.end (), pelement);98 if(It! =elements.end ()) About { - Elements.erase (it);101 }102 }103 104 voidObjectstructure::accept (Visitor *pvisitor) the {106 //set the visitor for each element to perform the corresponding operation107 for(vector<element *>::const_iterator it = Elements.begin (); It! = Elements.end (); + +it)108 {109(*it)Accept (pvisitor); the }111 } the 113 intMain () the { theObjectstructure *pobject =Newobjectstructure; the 117Concreteelementa *pelementa =NewConcreteelementa;118CONCRETEELEMENTB *PELEMENTB =NewConcreteelementb;119 -Pobject->Attach (Pelementa);121Pobject->Attach (PELEMENTB);122 123ConcreteVisitor1 *pvisitor1 =NewConcreteVisitor1;124ConcreteVisitor2 *pvisitor2 =NewConcreteVisitor2; the 126Pobject->Accept (pVisitor1);127Pobject->Accept (PVISITOR2); - 129 if(PVISITOR2)DeletePVisitor2; the if(PVisitor1)DeletePVisitor1;131 if(PELEMENTB)DeletePelementb; the if(Pelementa)DeletePelementa;133 if(pobject)DeletePobject;134 135 return 0;136}
Summarize
The basic idea of the visitor pattern is as follows: First, you have an object structure consisting of many objects, which is the objectstructure in the above code, and the classes of these objects have an accept method to receive the visitor object; The visitor is an interface that has a visit method, This method makes different operations on different types of elements in the object structure accessed, and during one access to the object structure, we traverse the entire object structure, implement an accept method for each element, and callback the visitor's visit method in each element's accept method, This allows the visitor to handle every element of the object structure. We can design different visitor classes for the object structure to do different things.
One of the most common words in design patterns is finding change and encapsulating it. Whether to use the visitor model depends on what "change" is. In the visitor pattern, the "change" is the specific visitor, followed by the object structure, but if the specific element also changes, it is absolutely impossible to use the visitor pattern, because this "reaching", later maintenance is too poor.
C + + Design mode-visitor mode