设计模式(4)--对象行为(11)--访问者

1. 意图

表示一个作用于某对象结构中的各元素的操作。

使你可以在不改变各元素的类的前提下定义于作用于这些元素的新操作。

2. 五种角色

抽象访问者(Visitor)、具体访问者(Concrete Visitor)、抽象元素(Element)、

具体元素(Concrete Element)、对象结构(ObjectStructure)

3. 优点

3.1 易于增加新的操作

3.2 集中相关的操作,而分离无关的操作

3.3 可以访问不具有相同父类的对象

4. 缺点

4.1 增加新的具体元素很困难

4.2 可能累积状态

4.3 可能破坏元素的封装性

5. 相关模式

5.1 访问者可以对一个由Composite模式定义的对象结构进行操作。

5.2 访问者可以用于解释器。

6. 代码示意
cpp 复制代码
#pragma once
#include <vector>
#include <string>
#include <iostream>
using namespace std;

class ElementA;
class ElementB;

class Visitor
{
public:
	virtual void VisitElementA(ElementA* pElementA) = 0;
	virtual void VisitElementB(ElementB* pElementB) = 0;
};

class ConcreteVisitor1 : public Visitor
{
public:
	virtual void VisitElementA(ElementA* pElementA);
	virtual void VisitElementB(ElementB* pElementB);
};
class ConcreteVisitor2 : public Visitor
{
public:
	virtual void VisitElementA(ElementA* pElementA);
	virtual void VisitElementB(ElementB* pElementB);
};

class Element
{
public:
	virtual void Accept(Visitor* pVisitor) = 0;
};

class ElementA : public Element
{
public:
	virtual void Accept(Visitor* pVisitor) {
		pVisitor->VisitElementA(this);
	}
	void OperationA(const string& name) {
		cout << "ElementA 来自 " << name << " 的访问" << endl;
	}
};

class ElementB : public Element
{
public:
	virtual void Accept(Visitor* pVisitor) {
		pVisitor->VisitElementB(this);
	}
	void OperationB(const string& name) {
		cout << "ElementB 来自 " << name << " 的访问" << endl;
	}
};


class ObjectStructure
{
	vector<Element*> m_elememts;
public:
	ObjectStructure() {
		m_elememts.emplace_back(new ElementA());
		m_elememts.emplace_back(new ElementB());
	}
	~ObjectStructure() {
		auto it = m_elememts.begin();
		while (it != m_elememts.end()) {
			delete* it;
			++it;
		}
	}
	void Visit(Visitor* pVisitor) {
		auto it = m_elememts.begin();
		while (it != m_elememts.end()) {
			(*it)->Accept(pVisitor);
			++it;
		}
	}
};

Visitor.cpp:

cpp 复制代码
#include "Visitor.h"

void ConcreteVisitor1::VisitElementA(ElementA* pElementA) {
	pElementA->OperationA("Visitor1");
}

void ConcreteVisitor1::VisitElementB(ElementB* pElementB) {
	pElementB->OperationB("Visitor1");
}

void ConcreteVisitor2::VisitElementA(ElementA* pElementA) {
	pElementA->OperationA("Visitor2");
}

void ConcreteVisitor2::VisitElementB(ElementB* pElementB) {
	pElementB->OperationB("Visitor2");
}
cpp 复制代码
#include "Visitor.h"
int main() {
	ObjectStructure* pObjStructure = new ObjectStructure();
	Visitor* pVisitor = new ConcreteVisitor1();
	pObjStructure->Visit(pVisitor);
	delete pVisitor;

	pVisitor = new ConcreteVisitor2();
	pObjStructure->Visit(pVisitor);
	delete pVisitor;

	delete pObjStructure;
	return 0;
}

运行结果:

6.1 ObjectStructure提供访问所有元素的接口

6.2 增加新的ConcreteVisitor3就可以定义一个新的操作(3.1)

6.3 抽象Visitor里的接口集中了相关的操作(3.2)

6.4 增加新的ElementC,所有Visitor类和ObjectStructure都要修改(4.1)

相关推荐
君鼎5 小时前
C++设计模式——单例模式
c++·单例模式·设计模式
敲代码的 蜡笔小新6 小时前
【行为型之中介者模式】游戏开发实战——Unity复杂系统协调与通信架构的核心秘诀
unity·设计模式·c#·中介者模式
令狐前生6 小时前
设计模式学习整理
学习·设计模式
敲代码的 蜡笔小新8 小时前
【行为型之解释器模式】游戏开发实战——Unity动态公式解析与脚本系统的架构奥秘
unity·设计模式·游戏引擎·解释器模式
JANYI20189 小时前
嵌入式设计模式基础--C语言的继承封装与多态
java·c语言·设计模式
敲代码的 蜡笔小新13 小时前
【行为型之观察者模式】游戏开发实战——Unity事件驱动架构的核心实现策略
观察者模式·unity·设计模式·c#
琢磨先生David16 小时前
构建优雅对象的艺术:Java 建造者模式的架构解析与工程实践
java·设计模式·建造者模式
敲代码的 蜡笔小新1 天前
【行为型之策略模式】游戏开发实战——Unity灵活算法架构的核心实现策略
unity·设计模式·c#·策略模式
_yingty_1 天前
Java设计模式-策略模式(行为型)
java·设计模式·策略模式
炎芯随笔1 天前
【C++】【设计模式】生产者-消费者模型
开发语言·c++·设计模式