Features
The primary data structure and the data separating operation
solve
- Mainly to solve: a stable and variable data structure operatively coupled problems
- When to use: the need for a target structure objects and many different unrelated operations, these operations need avoid "contamination" of these classes of objects, these packages use of visitors to the class
- How to fix: add a reception of foreign visitors to provide interfaces to be accessed inside the class
- The key code: the data base class which has a method to accept visitors, visitors will pass its own reference
Advantages and disadvantages
- advantage:
- In line with the principle of single responsibility
- Excellent scalability
- flexibility
- Disadvantages:
- Specific elements of the visitor announced details of a violation of the principle of Demeter
- Specific elements of change more difficult
- Violates the Dependency Inversion principle, we rely on a specific class that does not rely on abstract
Scenarios
- Application examples: You friend's house guest, you are a visitor, a friend accepts your access, through your friend's description, then the description of a friend make a judgment, which is the visitor pattern
- scenes to be used:
- Object structure rarely changes corresponding to the object class, but often need to define a new operation on this object structure
- The need for a lot of different and unrelated to the operation of a target object structure, and these actions need to avoid "contamination" class of these objects, do not want to modify these classes when adding new operations
- Note: Visitors can be unified function, you can make a report, UI, interceptor filter
Simple example code section
Visitor.h
#ifndef _VISITOR_H_
#define _VISITOR_H_
#include <iostream>
using namespace std;
class ConcreteElementA;
class ConcreteElementB;
class Element;
class Visitor{
public:
virtual ~Visitor(){}
virtual void VisitConcreteElementA(Element* elm) = 0;
virtual void VisitConcreteElementB(Element* elm) = 0;
protected:
Visitor(){}
};
class ConcreteVisitorA:public Visitor {
public:
ConcreteVisitorA(){}
virtual ~ConcreteVisitorA(){}
virtual void VisitConcreteElementA(Element* elm){
cout<<"i will visit ConcreteElementA..."<<endl;
}
virtual void VisitConcreteElementB(Element* elm){
cout<<"i will visit ConcreteElementB..."<<endl;
}
};
class ConcreteVisitorB:public Visitor {
public:
ConcreteVisitorB(){}
virtual ~ConcreteVisitorB(){}
virtual void VisitConcreteElementA(Element* elm){
cout<<"i will visit ConcreteElementA..."<<endl;
}
virtual void VisitConcreteElementB(Element* elm){
cout<<"i will visit ConcreteElementB..."<<endl;
}
};
class Element{
public:
virtual ~Element(){}
virtual void Accept(Visitor* vis) = 0;
protected:
Element(){}
};
class ConcreteElementA:public Element {
public:
ConcreteElementA(){}
~ConcreteElementA(){}
void Accept(Visitor* vis){
vis->VisitConcreteElementA(this);
cout<<"visiting ConcreteElementA..."<<endl;
}
};
class ConcreteElementB:public Element {
public:
ConcreteElementB(){}
~ConcreteElementB(){}
void Accept(Visitor* vis){
cout<<"visiting ConcreteElementB..."<<endl;
vis->VisitConcreteElementB(this);
}
};
#endif
main.cpp
#include "Visitor.h"
#include <iostream>
using namespace std;
int main() {
Visitor* vis = new ConcreteVisitorA();
Element* elm = new ConcreteElementA();
elm->Accept(vis);
return 0;
}