第28章访问者模式

一 概念

  • 访问者模式,表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

二 访问者模式的优点和缺点

  • 访问者模式适用于数据结构比较稳定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化
  • 访问者模式的优点就是增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者,访问者模式将有关的行为集中到一个访问者对象中。
  • 访问者模式的缺点其实也就是使增加新的数据结构变得困难了。

三 C++代码实现
Visitor.h

#pragma once
#include <iostream>
#include <string>
#include <list>
using namespace std;
class Action;  //类的前向声明
//人的抽象类
class Person
{
public:
	virtual void Accept(Action* visitor) = 0;
};
//状态的抽象类
class Action
{
public:
	virtual void GetManConclusion(Person* concreteElementA) = 0;
	virtual void GetWomanConclusion(Person* concreteElementA) = 0;
};
class Man : public Person
{
public:
	Man()
	{}
	void Accept(Action* visitor) override
	{
		visitor->GetManConclusion(this);
	}
};
class Woman : public Person
{
public:
	Woman()
	{}

	void Accept(Action* visitor) override
	{
		visitor->GetWomanConclusion(this);
	}
private:
	string m_woman;
};

//具体状态类
class Success : public Action
{
public:
	void GetManConclusion(Person* concreteElementA) override
	{
		cout << typeid(*concreteElementA).name() << " " << typeid(*this).name() << " "
			<< "时,背后多半有一个伟大的女人" << endl;
	}
	void GetWomanConclusion(Person* concreteElementA) override
	{
		cout << typeid(*concreteElementA).name() << " " << typeid(*this).name() << " "
			<< "时,背后多半有一个不成功的男人" << endl;
	}
};
//失败
class Failing : public Action
{
public:
	void GetManConclusion(Person* concreteElementA) override
	{
		cout << typeid(*concreteElementA).name() << " " << typeid(*this).name() << " "
			<< "闷头喝酒,谁也不用劝" << endl;
	}
	void GetWomanConclusion(Person* concreteElementA) override
	{
		cout << typeid(*concreteElementA).name() << " " << typeid(*this).name() << " "
			<< "眼泪汪汪,谁也劝不了" << endl;
	}
};
//恋爱
class Amativeness : public Action
{
public:
	void GetManConclusion(Person* concreteElementA) override
	{
		cout << typeid(*concreteElementA).name() << " " << typeid(*this).name() << " "
			<< "凡事不懂也要装懂" << endl;
	}
	void GetWomanConclusion(Person* concreteElementA) override
	{
		cout << typeid(*concreteElementA).name() << " " << typeid(*this).name() << " "
			<< "凡事懂也装不懂" << endl;
	}
};

class ObjectStructure
{
public:
	void Attach(Person* element)
	{
		elements.push_back(element);
	}
	void Detach(Person* element)
	{
		for (list<Person*>::iterator it = elements.begin(); it!= elements.end(); ++it)
		{
			if (*it == element)
			{
				elements.erase(it);
				break;
			}
		}
	}
	void Display(Action* visitor)
	{
		//遍历方法
		list<Person* >::iterator it;
		for (it = elements.begin(); it != elements.end(); it++)
			(*it)->Accept(visitor);
	}
private:
	list<Person*> elements;
};

lesson1.cpp

#include "Visitor.h"
#include <iostream>
using namespace std;

int main()
{
	ObjectStructure* o = new ObjectStructure();
	Person* man = new Man();
	Person* woman = new Woman();
	o->Attach(man);
	o->Attach(woman);

	//成功时的反应
	Success* v1 = new Success();
	o->Display(v1);

	o->Detach(woman);

	//失败时的反应
	Failing* v2 = new Failing();
	o->Display(v2);

	o->Attach(woman);

	Amativeness* v3 = new Amativeness();
	o->Display(v3);
	return 0;
}

运行结果

原文地址:https://www.cnblogs.com/Manual-Linux/p/11167674.html