Visitor mode of design mode (C++)

Author: Zhai Tianbao Steven
Copyright statement: The copyright belongs to the author. For commercial reprint, please contact the author for authorization. For non-commercial reprint, please indicate the source

1. What is the visitor pattern?

       The Visitor pattern is a behavioral software design pattern that represents an operation on elements in an object structure. Allows the definition of operations on these elements without changing the class of each element.

       This mode is suitable for systems with relatively stable data structures and easy-to-change algorithms. The data structure is the visitor, and the algorithm operation is equivalent to the visitor.

       Advantages of the visitor pattern:

  1. Good scalability. To extend operations on elements, only need to add visitors.
  2. Meet the Single Responsibility Principle. Related operations are encapsulated as a visitor, making the visitor have a single responsibility.
  3. Decoupling. The data structure itself is decoupled from the operations that operate on it.

       Disadvantages of visitor pattern:

  1. It is not easy to add element classes. For each additional element class, the interface and implementation of the visitor must be changed.
  2. Violates the Dependency Inversion Principle. Visitors depend on concrete elements rather than abstract elements.
  3. breaks the package. A visitor can get details of the element being visited.

2. Visitor mode

2.1 Structure diagram

       The client is the main function. The object structure stores the set of elements to be accessed and the method of traversing each element, so that the abstract visitor can connect with the specific elements in turn to complete the access.

2.2 Code example

       Scene description: The mayor inspects schools and businesses.

//Visitor.h
/****************************************************/
#pragma once
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

class Visitor;

// 抽象元素类-地点(被访问)
class Place 
{
public:
	// 构造函数
	Place(string name) : m_name(name) {}

	// 接受访问
	virtual void accept(Visitor* visitor) = 0;

	// 获取名字
	string getName() {
		return m_name;
	}

private:
	string m_name;
};

// 具体元素类-学校
class School : public Place 
{
public:
	// 构造函数
	School(string name) : Place(name) {}

	// 接受访问
	virtual void accept(Visitor* visitor);

};

// 具体元素类-企业
class Enterprise : public Place 
{
public:
	// 构造函数
	Enterprise(string name) : Place(name) {}

	// 接受访问
	virtual void accept(Visitor* visitor);

};

// 抽象访问者
class Visitor 
{
public:
	// 访问学校
	virtual void visitSchool(School* school) = 0;

	// 访问企业
	virtual void visitEnterprise(Enterprise* enterprise) = 0;

};

// 具体访问者-市长
class Mayor : public Visitor 
{
public:
	// 访问学校
	virtual void visitSchool(School* school) {
		cout << "市长参观了:" << school->getName() << endl;
		cout << "对老师和学生表达了诚挚的慰问。" << endl;
	}

	// 访问企业
	virtual void visitEnterprise(Enterprise* enterprise) {
		cout << "市长参观了:" << enterprise->getName() << endl;
		cout << "对企业的发展表示肯定。" << endl;
	}

};

// 访问行为类
class Visiting
{
public:
	// 添加被访问地点
	void add(Place* place) {
		places.push_back(place);
	}

	// 删除被访问地点
	void remove(Place* place) {
		places.erase(std::remove(places.begin(), places.end(), place), places.end());
	}

	// 进行访问
	void accept(Visitor* visitor) {
		for (auto place : places) {
			place->accept(visitor);
		}
	}

private:
	std::vector<Place*> places;
};
//Visitor.cpp
/****************************************************/
#include "Visitor.h"

// 接受访问
void School::accept(Visitor* visitor) {
	visitor->visitSchool(this);
}

// 接受访问
void Enterprise::accept(Visitor* visitor) {
	visitor->visitEnterprise(this);
}
//main.cpp
/****************************************************/
#include <iostream>
#include <string>
#include "Visitor.h"

using namespace std;

int main() 
{
	Visiting *visiting = new Visiting();
	Place *school = new School("东华大学");
	Place *enterprise = new Enterprise("华为");
	Visitor *mayor = new Mayor();

	// 添加被访问对象
	cout << "首日,";
	visiting->add(school);
	visiting->add(enterprise);
	// 安排市长进行访问
	visiting->accept(mayor);
	// 次日行程,删除某个被访问对象后再次访问
	cout << "次日,";
	visiting->remove(school);
	visiting->accept(mayor);

	// 删除
	delete visiting;
	delete school;
	delete enterprise;
	delete mayor;
	visiting = nullptr;
	school = nullptr;
	enterprise = nullptr;
	mayor = nullptr;

	return 0;
}

       The program results are as follows.

       The visitor mode decouples the access operation from the accessed elements. When visiting schools and enterprises, different visitors have different things and purposes, and this different content can be implemented in the visitor class. However, this mode is not suitable for adding new elements, just like adding a new visited object-the police station, then every visitor must add the operation of visiting the police station, which violates the principle of opening and closing.

3. Summary

       I try my best to express my understanding of the visitor mode with more popular words and intuitive code routines. There may be some places that are not thoughtful. If you have different opinions, welcome to exchange in the comment area! Hope my example will help you understand the visitor pattern better.

       If the article helps you, you can give me a like to let me know, I will be very happy ~ come on!

Guess you like

Origin blog.csdn.net/zhaitianbao/article/details/130319735