访问者模式复习及C++实现

本文深入解析访问者模式,一种行为型设计模式,用于定义对象结构上元素的新操作,无需修改元素类。通过实例演示,展示如何在不改变元素类的前提下,增加新操作,适用于易于增加新操作和集中相关操作的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 意图:GOF的书上有这样的描述:表示一个作用于某对象结构中的各个元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

类图结构

演示模型和代码

这里的访问者是水费收费员(VisitorWater)和电费收费员(VisitorElectric),对象结构是整个村庄(Village), 各元素为各个具体家庭((小华家)FamilyXiaoHua、(小明家)FamilyXiaoMing,(李宁家)FamilyLiNing ) 。其实看完这个实例的代码就可以大体理解上面意图中的描述了:"作用于对象结构中的对各个元素额操作",这里的对各个元素的操作其实就是定义在基类Visitor中的各个接口,“它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作",这句话其实是通过定义具体的访问者并实现自定义的具体接口来实现的。

#include <iostream>
#include <string>

using namespace std;

class FamilyXiaoHua;
class FamilyXiaoMing;
class FamilyLiNing;
class Visitor;

class Family
{
public:
	Family(std::string name){
		m_name = name;
	}

	virtual ~Family(){}

	std::string name() { return m_name; }
protected:
	virtual void Accept(Visitor* visitor) = 0;
protected:
	std::string m_name;
};

class Visitor
{
public:
	Visitor() {}

	virtual ~Visitor() {}

	virtual void visitFamilyXiaoHua(FamilyXiaoHua* fxh)
	{

	}
	virtual void visitFamilyXiaoMing(FamilyXiaoMing* fxm)
	{

	}
	virtual void visitFamilyLiNing(FamilyLiNing* flm)
	{

	}
private:
};

class FamilyXiaoHua : public Family
{
public:
	FamilyXiaoHua(): Family("FamilyXiaoHua"){
	}

	~FamilyXiaoHua() {}
	friend class Village;
private:
	virtual void Accept(Visitor* visitor);
};

void FamilyXiaoHua::Accept(Visitor* visitor) {
	visitor->visitFamilyXiaoHua(this);
}

class FamilyXiaoMing : public Family
{
public:
	FamilyXiaoMing() : Family("FamilyXiaoMing"){
	}

	~FamilyXiaoMing(){}
	friend class Village;
private:
	virtual void Accept(Visitor* visitor);
};

void FamilyXiaoMing::Accept(Visitor* visitor) {
	visitor->visitFamilyXiaoMing(this);
}

class FamilyLiNing : public Family
{
public:
	FamilyLiNing() : Family("FamilyLiNing") {
	}

	~FamilyLiNing(){}
	friend class Village;
private:
	virtual void Accept(Visitor* visitor);
};

void FamilyLiNing::Accept(Visitor* visitor) {
	visitor->visitFamilyLiNing(this);
}

class Village
{
public:
	Village(FamilyXiaoHua *fxh,FamilyXiaoMing *fxm,
				FamilyLiNing *fln){

		m_fxh = fxh;
		m_fxm = fxm;
		m_fln = fln;
	}

	~Village(){

		if (m_fxh) delete m_fxh;
		if (m_fxm) delete m_fxm;
		if (m_fln) delete m_fln;
	}

	void Accept(Visitor *visitor)
	{
		m_fxh->Accept(visitor);
		m_fxm->Accept(visitor);
		m_fln->Accept(visitor);
	}

private:
	FamilyXiaoHua* m_fxh;
	FamilyXiaoMing* m_fxm;
	FamilyLiNing* m_fln;
};

class VisitorWater : public Visitor
{
public:
	VisitorWater(){

	}

	~VisitorWater(){}

	virtual void visitFamilyXiaoHua(FamilyXiaoHua* fxh)
	{
		cout << "This is VisitorWater to visit " << fxh->name() << endl;
	}
	virtual void visitFamilyXiaoMing(FamilyXiaoMing* fxm)
	{
		cout << "This is VisitorWater to visit " << fxm->name() << endl;
	}
	virtual void visitFamilyLiNing(FamilyLiNing* flm)
	{
		cout << "This is VisitorWater to visit " << flm->name() << endl;
	}
private:
};

class VisitorElectric : public Visitor
{
public:
	VisitorElectric(){

	}

	~VisitorElectric(){}

	virtual void visitFamilyXiaoHua(FamilyXiaoHua* fxh)
	{
		cout << "This is VisitorElectric to visit " << fxh->name() << endl;
	}

	virtual void visitFamilyXiaoMing(FamilyXiaoMing* fxm)
	{
		cout << "This is VisitorElectric to visit " << fxm->name() << endl;
	}

	virtual void visitFamilyLiNing(FamilyLiNing* flm)
	{
		cout << "This is VisitorElectric to visit " << flm->name() << endl;
	}
private:
};

int main(int argc, char *argv[])
{

    FamilyXiaoHua *fxh = new FamilyXiaoHua();
    FamilyXiaoMing *fxm = new FamilyXiaoMing();
    FamilyLiNing* flm = new FamilyLiNing();

    Village* village = new Village(fxh, fxm, flm);
    VisitorWater* visitorW = new VisitorWater();
    VisitorElectric* visitorE = new VisitorElectric();

    village->Accept(visitorW);

    village->Accept(visitorE);

    return 0;
}

运行输出:

 此模式的优缺点

1.访问者模式使得易于增加新的操作;

2.访问者集中相关的操作而分离无关的操作;

3.增加新的ConcreteElement类很困难;

4.通过类层次进行访问;

5.累积状态;

6.破坏封装;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值