C++ 大话设计之《访问者模式》(优缺点,设计原理,常用场景)

访问者模式允许在不修改对象结构的情况下增加新的操作。它常用于编译器设计,对抽象语法树执行操作如类型检查和代码生成。这种模式遵循开放封闭原则,方便扩展但避免修改原有代码。示例展示了如何创建和使用访问者模式的类结构。
摘要由CSDN通过智能技术生成

访问者模式是一种行为型模式


优点:

能够在不改变对象结构的情况下增加新的操作,使得操作集合可以相对独立地演化。

缺点:

  • 增加新的元素类变得困难,因为每个新元素都必须被访问者类所接受。
  • 此外,如果对象结构中的元素类经常发生变化,那么使用访问者模式可能不是最佳选择。

满足的设计原则:

访问者模式满足了开放封闭原则(Open-Closed Principle,OCP)。这个原则指出软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。访问者模式允许你在不改变对象结构中元素类的情况下定义一个新的操作,这样就可以在不修改现有代码的情况下增加新的功能。
 

常用实例:

访问者模式在开发中的一个常见应用是编译器。编译器通常需要对抽象语法树(AST)进行遍历,以执行诸如类型检查、代码生成等操作。使用访问者模式,可以将这些操作定义为访问者类,然后在遍历AST时调用相应的访问者方法。这样,当需要增加新的操作时,只需定义一个新的访问者类即可,而无需修改AST的结构。

类图:

 代码:

#include "iostream"
#include "vector"

using namespace std;

class ConcreteElementA;
class ConcreteElementB;

class Visitor
{
public:
	virtual void visitConcreteElementA(ConcreteElementA*elementA)=0;
	virtual void visitConcreteElementB(ConcreteElementB*elementB)=0;
};

class Element
{
public:
	virtual void accept(Visitor*visitor)=0;

};

class ConcreteElementA :public Element
{
public:
	void accept(Visitor* visitor)
	{
		visitor->visitConcreteElementA(this);
	}
	void operationA()
	{
		cout<<"ConcreteElementA operation"<<endl;
	}
};

class ConcreteElementB :public Element
{
public:
	void accept(Visitor* visitor)
	{
		visitor->visitConcreteElementB(this);
	}
	
	void operationB()
	{
		cout<<"ConcreteElementB operation"<<endl;
	}


};

class ConcreteVisitor1 :public Visitor
{
public:
	void visitConcreteElementA(ConcreteElementA* elementA)
	{
		elementA->operationA();
	}

	void visitConcreteElementB(ConcreteElementB* elementB)
	{
		elementB->operationB();
	}
};

class ConcreteVisitor2 :public Visitor
{
public:
	void visitConcreteElementA(ConcreteElementA* elementA)
	{
		elementA->operationA();
	}

	void visitConcreteElementB(ConcreteElementB* elementB)
	{
		elementB->operationB();
	}
};



class ConcreteVisitor3 :public Visitor
{
public:
	void visitConcreteElementA(ConcreteElementA* elementA)
	{
		elementA->operationA();
		//可在此处扩展
		cout<<"sss"<<endl;
	}

	void visitConcreteElementB(ConcreteElementB* elementB)
	{
		elementB->operationB();
		//可在此处扩展
		cout << "sss" << endl;
	}
};

class ObjectStructure
{
public:
	void attach(Element* element)
	{
		elements.push_back(element);
	}
	void detach(Element* element)
	{
		for (vector<Element*>::iterator it=elements.begin();it!=elements.end();++it)
		{
			if (*it == element)
			{
				elements.erase(it);
				break;
			}
		}
	}

	void accept(Visitor* visitor)
	{
		for (auto elment : elements)
		{
			elment->accept(visitor);
		}
	}




private:
	vector<Element*>elements;
};

int main()
{
	
	ObjectStructure objectStructure;

	ConcreteElementA elementA;
	ConcreteElementB elementB;

	objectStructure.attach(&elementA);
	objectStructure.attach(&elementB);

	ConcreteVisitor1 visitor1;
	ConcreteVisitor2 visitor2;

	objectStructure.accept(&visitor1);

	objectStructure.accept(&visitor2);




	return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值