访问者模式(Visitor):
表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
访问者模式适用于数据结构相对稳定的系统。
它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化。
访问者模式的目的是要把处理从数据结构中分离出来 ,如果系统有比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式就比较合适,因为访问者模式使得算法我操作的增加变得容易。
访问者的优点是增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者,将有关的行为集中到一个访问对象中。
缺点是使增加新的数据结构变得困难了(下面是《大话设计模式》结构图↓↓↓)。
这个模式想不到在什么地方使用啊......
代码:
#include <iostream>
#include <string>
#include <list>
using namespace std;
class Visitor;
class Element
{
public:
Element(string _name):name(_name) {}
virtual ~Element() {}
virtual void Accept(Visitor* v) = 0;
string name;
};
class ConcreteElemetA :public Element
{
Visitor* visitor;
public:
ConcreteElemetA(string _name) :Element(_name) {}
~ConcreteElemetA() {}
// 通过 Element 继承
virtual void Accept(Visitor* v) override
{
visitor = v;
}
void OperationA()
{}
};
class ConcreteElemetB :public Element
{
Visitor* visitor;
public:
ConcreteElemetB(string _name) :Element(_name) {}
~ConcreteElemetB() {}
// 通过 Element 继承
virtual void Accept(Visitor* v) override
{
visitor = v;
}
void OperationA()
{}
};
class Visitor
{
public:
Visitor(string _name) :name(_name) {}
virtual ~Visitor() {}
virtual void VisitConcreteElementA(ConcreteElemetA* e) = 0;
virtual void VisitConcreteElementB(ConcreteElemetB* e) = 0;
string name;
};
class ConcreteVisitor1 :public Visitor
{
public:
ConcreteVisitor1(string _name):Visitor(_name) {}
~ConcreteVisitor1()
{}
// 通过 Visitor 继承
virtual void VisitConcreteElementA(ConcreteElemetA* e) override
{
cout << e->name << " visit " << this->name << endl;
}
virtual void VisitConcreteElementB(ConcreteElemetB* e) override
{
cout << e->name << " visit " << this->name << endl;
}
};
class ConcreteVisitor2 :public Visitor
{
public:
ConcreteVisitor2(string _name) :Visitor(_name) {}
~ConcreteVisitor2()
{}
// 通过 Visitor 继承
virtual void VisitConcreteElementA(ConcreteElemetA* e) override
{
cout << e->name << " visit " << this->name << endl;
}
virtual void VisitConcreteElementB(ConcreteElemetB* e) override
{
cout << e->name << " visit " << this->name << endl;
}
};
class ObjectStructur
{
private:
list<Element*> ele_list;
public:
ObjectStructur() {}
~ObjectStructur()
{
for (auto mem : ele_list)
{
delete mem;
}
}
void Attach(Element* e)
{
ele_list.push_back(e);
}
void Detach(Element* e)
{
ele_list.remove(e);
}
void Accpet(Visitor* v)
{
for (auto mem : ele_list)
{
mem->Accept(v);
}
}
};
int main()
{
ObjectStructur o;
o.Attach(new ConcreteElemetA("ConcreteElementA"));
o.Attach(new ConcreteElemetA("ConcreteElementA"));
ConcreteVisitor1 v1("ConcreteVisitor1");
ConcreteVisitor2 v2("ConcreteVisitor2");
o.Accpet(&v1);
o.Accpet(&v2);
getchar();
return 0;
}