(本博客旨在个人总结回顾)
1、详情:
访问者模式:表示一个作用于某对象结构中各元素的操作。它可以使你在不改变这些元素的类的前提下,定义作用于这些元素的新操作。
说明:
优点:
①符合单一职责原则。
②优秀的扩展性 、灵活性。
缺点:
①具体元素对访问者公布细节,违反了迪米特原则。
②具体元素变更比较困难。
③违反了依赖倒置原则,依赖了具体类,没有依赖抽象。
使用场景:
①对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。
②需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。
2.1、UML类图:
2.2、例子源码
stdafx.h
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <iostream>
using namespace std;
// TODO: 在此处引用程序需要的其他头文件
Visitor.h(访问者接口类)
#pragma once
#include "Element.h"
class Element;
class Visitor
{
public:
Visitor();
virtual ~Visitor();
public:
virtual void VisitElementX(Element* pElement) = 0;
virtual void VisitElementY(Element* pElement) = 0;
};
Visitor.cpp
#include "stdafx.h"
#include "Visitor.h"
Visitor::Visitor()
{
}
Visitor::~Visitor()
{
}
Visitor1.h(具体访问者1)
#pragma once
#include "Visitor.h"
class Visitor1 :
public Visitor
{
public:
Visitor1();
~Visitor1();
public:
void VisitElementX(Element* pElement);
void VisitElementY(Element* pElement);
}
Visitor1.cpp
#include "stdafx.h"
#include "Visitor1.h"
Visitor1::Visitor1()
{
}
Visitor1::~Visitor1()
{
}
void Visitor1::VisitElementX(Element* pElement)
{
cout << typeid(*pElement).name() << " 被" << typeid(this).name() << "访问!"<< endl;
}
void Visitor1::VisitElementY(Element* pElement)
{
cout << typeid(*pElement).name() << " 被" << typeid(this).name() << "访问!" << endl;
}
Visitor2.h(具体访问者2)
#pragma once
#include "Visitor.h"
class Visitor2 :
public Visitor
{
public:
Visitor2();
~Visitor2();
public:
void VisitElementX(Element* pElement);
void VisitElementY(Element* pElement);
};
Visitor2.cpp
#include "stdafx.h"
#include "Visitor2.h"
Visitor2::Visitor2()
{
}
Visitor2::~Visitor2()
{
}
void Visitor2::VisitElementX(Element* pElement)
{
cout << typeid(*pElement).name() << " 被" << typeid(this).name() << "访问!" << endl;
}
void Visitor2::VisitElementY(Element* pElement)
{
cout << typeid(*pElement).name() << " 被" << typeid(this).name() << "访问!" << endl;
}
Element.h(元素接口类)
#pragma once
#include "Visitor.h"
class Visitor;
class Element
{
public:
Element();
virtual ~Element();
public:
virtual void Accept(Visitor* pVisitor) = 0;
};
Element.cpp
#include "stdafx.h"
#include "Element.h"
Element::Element()
{
}
Element::~Element()
{
}
ElementX.h(具体元素X)
#pragma once
#include "Element.h"
class ElementX :
public Element
{
public:
ElementX();
~ElementX();
public:
void Accept(Visitor* pVisitor);
void OperationX();
};
ElementX.cpp
#include "stdafx.h"
#include "ElementX.h"
ElementX::ElementX()
{
}
ElementX::~ElementX()
{
}
void ElementX::Accept(Visitor* pVisitor)
{
pVisitor->VisitElementX(this);
}
void ElementX::OperationX()
{
cout << "ElementX operationX" << endl;
}
ElementY.h(具体元素类Y)
#pragma once
#include "Element.h"
class ElementY :
public Element
{
public:
ElementY();
~ElementY();
public:
void Accept(Visitor* pVisitor);
void OperationY();
};
ElementY.cpp
#include "stdafx.h"
#include "ElementY.h"
ElementY::ElementY()
{
}
ElementY::~ElementY()
{
}
void ElementY::Accept(Visitor* pVisitor)
{
pVisitor->VisitElementY(this);
}
void ElementY::OperationY()
{
cout << "ElementY OperationX!" << endl;
}
ObjectStructure.h(结构类)
#pragma once
#include<list>
#include "Element.h"
#include "Visitor.h"
class ObjectStructure
{
public:
ObjectStructure();
~ObjectStructure();
public:
void Add(Element* pElement);
void Remove(Element* pElement);
void Accept(Visitor* pVisitor);
private:
std::list<Element*> m_listElement;
};
ObjectStructure.cpp
#include "stdafx.h"
#include "ObjectStructure.h"
ObjectStructure::ObjectStructure()
{
}
ObjectStructure::~ObjectStructure()
{
for (std::list<Element*>::iterator it = m_listElement.begin(); it != m_listElement.end(); it++)
{
delete (*it);
}
m_listElement.clear();
}
void ObjectStructure::Add(Element* pElement)
{
if (pElement != NULL)
{
m_listElement.push_back(pElement);
}
}
void ObjectStructure::Remove(Element* pElement)
{
if (pElement != NULL)
{
delete pElement;
m_listElement.remove(pElement);
}
}
void ObjectStructure::Accept(Visitor* pVisitor)
{
for (std::list<Element*>::iterator it = m_listElement.begin(); it != m_listElement.end(); it++)
{
(*it)->Accept(pVisitor);
}
}
调用代码
VisitorPatternMemo.cpp
// VisitorPatternMemo.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "ObjectStructure.h"
#include "ElementX.h"
#include "ElementY.h"
#include "Visitor1.h"
#include "Visitor2.h"
int _tmain(int argc, _TCHAR* argv[])
{
ObjectStructure objectStructure;
objectStructure.Add(new ElementX());
objectStructure.Add(new ElementY());
objectStructure.Accept(new Visitor1());
objectStructure.Accept(new Visitor2());
system("pause");
return 0;
}
2.3、运行结果: