[design mode] behavioral mode Visitor mode

function

Mainly separate data structure and data operation

Solve

  • Main solution: stable data structure and changeable operation coupling
  • When to use: you need to perform many different and unrelated operations on the objects in an object structure, but you need to avoid these operations "contaminating" the classes of these objects, and use the visitor pattern to encapsulate these into the classes
  • How to solve this problem: add an external interface to the visited class to receive visitors
  • Key code: in the data base class, there is a method to accept visitors and pass their own references to visitors

Advantages and disadvantages

  • Advantage:
    • Conform to the principle of single responsibility
    • Excellent scalability
    • flexibility
  • Disadvantages:
    • It is against Dimitar's principle to publish details to visitors
    • It is difficult to change specific elements
    • Violation of dependency inversion principle, dependence on concrete classes, no dependence on abstraction

Application scenario

  • Application example: you are a visitor in a friend's home. A friend accepts your visit. You make a judgment on the description of a friend through the description of the friend. This is the visitor mode
  • Usage scenario:
    • The classes corresponding to the objects in the object structure rarely change, but new operations are often needed to be defined on the object structure
    • You need to perform many different and unrelated operations on objects in an object structure, and you need to avoid these operations "contaminating" the classes of these objects, and you don't want to modify these classes when adding new operations
  • Note: visitors can unify functions and make reports, UI, interceptors and filters

Simple sample 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;
}
Published 64 original articles, won praise 3, visited 6164
Private letter follow

Posted on Sat, 15 Feb 2020 04:06:47 -0500 by willcodeforfoo