访问者模式(Visitor)
:表示一个作用于某个对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
- Visitor类,为该对象结构中ConcreteElement的每一个类声明一个Visit操作。
- ObjectStructure类,能枚举它的元素,可以提供一个高层的接口以充许访问者访问它的元素。可以针对不同的‘状态’遍历各具体Element得到不同的反应。
双分派技术
首先在客户程序中将具体状态作为参数传递给ConcreteElementA,然后ConcreteElementA类调用作为参数的“具体状态”中的方法对应算法片段,同时将自己(this)作为参数传递进去,这便完成了第二次分派。
双分派意味着得到执行的操作决定于请求的种类和两个接收者的类型。“接受”方法就是一个双分派的操作,它得到执行的操作不仅决定于‘状态’类的具体状态,还决定于它访问的“ConcreteElement#”的类别。
//客户端程序
ObjectStructure o =new 0bjectStructure();
o.Attach(new ConcreteElementA());
o.Attach(new ConcreteElementB());
class ConcreteElementA:public Element
{
public:
virtual void Accept (Visitor *visitor) override;
void OperationA();
}
void ConcreteElementA::Accept()
{
visitor->visitConcreteElementA(this); //充分利用双分派技术,实现处理与数据结构的分离
}
访问者模式应用分析
访问者模式适用数据结构相对稳定的系统。它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化
访问者的目的地要把处理从数据结构分离出来。如果有系统有比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式就是比较合适的,因为访问者模式使得算法操作的增加变得容易。即数据结构对象易于变化的系统则不适合使用访问者模式。
其优点是增加新的操作很容易,加为增加新的操作就意味增加一个新的访问者。访问者模式将有关的行为集中至一个访问者对象中。
缺点:使得增加新的数据结构变得困难了。
#include "ObjectStructure.h"
#include <iostream>
#include <cstdlib>
int main()
{
ObjectStructure o;
o.Attach(new Man());
o.Attach(new Woman());
Success v1;
o.Display(&v1);
Failing v2;
o.Display(&v2);
Amativeness v3;
o.Display(&v3);
system("pause");
}