第二十八章-访问者模式
访问者模式(Visitor): 表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
访问者模式适用于数据结构相对稳定的系统。它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化。访问者模式的目的是要把处理从数据结构分离出来。很多系统可以按照算法和数据结构分开,如果这样的系统有比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式就是比较适合的,因为访问者模式使得算法操作的增加变得容易。反之,如果这样的系统的数据结构对象易于变化,经常要有新的数据对象增加进来,就不适合使用访问者模式。
访问者模式的优点就是增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者,访问者模式将有关的行为集中到一个访问者对象中。
访问者的缺点其实也就是使增加新的数据结构变得困难了。
#include<vector>
using namespace std;
class Action;
class Person
{
public:
virtual void Accept(Action* visitor) = 0;
};
class Man :public Person
{
public:
void Accept(Action* visitor);
};
class Woman :public Person
{
public:
void Accept(Action* visitor);
};
class Action
{
public:
virtual void GetManConclusion(Man* concreteElementA) = 0;
virtual void GetWomanConclusion(Woman* concreteElementB) = 0;
};
class Success :public Action
{
public:
void GetManConclusion(Man* concreteElementA);
void GetWomanConclusion(Woman* concreteElementB);
};
class Failing :public Action
{
public:
void GetManConclusion(Man* concreteElementA);
void GetWomanConclusion(Woman* concreteElementB);
};
class Amativeness :public Action
{
public:
void GetManConclusion(Man* concreteElementA);
void GetWomanConclusion(Woman* concreteElementB);
};
class ObjectStructure
{
private:
vector<Person*> elements;
public:
void Attach(Person* element);
void Detach(Person* element);
void Display(Action* visitor);
};
#include <iostream>
#include<vector>
#include<string>
#include<ctime>
#include<unordered_map>
#include"work.h"
using namespace std;
void Man::Accept(Action* visitor)
{
visitor->GetManConclusion(this);
}
void Woman::Accept(Action* visitor)
{
visitor->GetWomanConclusion(this);
}
void Success::GetManConclusion(Man* concreteElementA)
{
cout << typeid(*concreteElementA).name() << typeid(*this).name() << "时,背后多半有一个伟大的女人。" << endl;
}
void Success::GetWomanConclusion(Woman* concreteElementB)
{
cout << typeid(*concreteElementB).name() << typeid(*this).name() << "时,背后多半有一个不成功的男人。" << endl;
}
void Failing::GetManConclusion(Man* concreteElementA)
{
cout << typeid(*concreteElementA).name() << typeid(*this).name() << "时,闷头喝酒,谁也不用劝。" << endl;
}
void Failing::GetWomanConclusion(Woman* concreteElementB)
{
cout << typeid(*concreteElementB).name() << typeid(*this).name() << "时,眼泪汪汪,谁也劝不了。" << endl;
}
void Amativeness::GetManConclusion(Man* concreteElementA)
{
cout << typeid(*concreteElementA).name() << typeid(*this).name() << "时,凡事不懂也要装懂。" << endl;
}
void Amativeness::GetWomanConclusion(Woman* concreteElementB)
{
cout << typeid(*concreteElementB).name() << typeid(*this).name() << "时,遇事懂也装作不懂。" << endl;
}
void ObjectStructure::Attach(Person* element)
{
elements.push_back(element);
}
void ObjectStructure::Detach(Person* element)
{
for (auto _i = elements.begin(); _i != elements.end(); _i++)
{
if (*_i == element)
{
elements.erase(_i);
break;
}
}
}
void ObjectStructure::Display(Action* visitor)
{
for (auto _i : elements)
{
_i->Accept(visitor);
}
}
int main()
{
ObjectStructure* o = new ObjectStructure();
o->Attach(new Man());
o->Attach(new Woman());
Success* v1 = new Success();
o->Display(v1);
Failing* v2 = new Failing();
o->Display(v2);
Amativeness* v3 = new Amativeness();
o->Display(v3);
system("pause");
return 0;
}