访问者模式(visitor),表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。访问者模式适用于数据结构相对稳定的系统。它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化。访问者模式的目的是要把处理从数据结构分离出来。很多系统可以按照算法和数据结构分开,如果这样的系统有比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式就是比较合适的,因为访问者模式使得算法操作的增加变得容易。反之,如果这样的系统的数据结构对象易于变化,经常要有新的数据对象增加进来,就不适合使用访问者模式。
访问者模式的优点就是增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者。访问者模式将有关的行为集中到一个访问者对象中。通常concreteVisitor可以单独开发,不必跟concreteElement写在一起。访问者的缺点其实也就是使增加新的数据结构变得困难了。
结构图:
访问者模式基本示例代码
访问者模式 visitor.h、concreteVisitor.h、element.h、concreteElement.h、objectStructure.h
客户端 visitorApp.cpp
访问者模式
visitor.h /************************************************************************ * description: 为该对象结构中ConcreteElement的每一个类声明一个visit操作 * remark: ************************************************************************/ #ifndef _VISITOR_H_ #define _VISITOR_H_ class concreteElementA; class concreteElementB; class visitor { public: visitor(){}; virtual ~visitor(){}; virtual void visitConcreteElementA(concreteElementA* pConcreteElementA) = 0; virtual void visitConcreteElementB(concreteElementB* pConcreteElementB) = 0; }; #endif// _VISITOR_H_
concreteVisitor.h
/************************************************************************ * description: 具体访问者,实现每个由visitor声明的操作。每个操作实现算法 的一部分,而该算法片断乃是对应于结构中对象的类 * remark: ************************************************************************/ #ifndef _CONCRETE_VISITOR_H_ #define _CONCRETE_VISITOR_H_ #include "visitor.h" #include <iostream> using namespace std; class concreteVisitor1 : public visitor { public: concreteVisitor1(){}; ~concreteVisitor1(){}; virtual void visitConcreteElementA(concreteElementA* pConcreteElementA) { cout << "concreteElementA被concreteVisitor1访问" << endl; } virtual void visitConcreteElementB(concreteElementB* pConcreteElementB) { cout << "concreteElementB被concreteVisitor1访问" << endl; } }; class concreteVisitor2 : public visitor { public: concreteVisitor2(){}; ~concreteVisitor2(){}; virtual void visitConcreteElementA(concreteElementA* pConcreteElementA) { cout << "concreteElementA被concreteVisitor2访问" << endl; } virtual void visitConcreteElementB(concreteElementB* pConcreteElementB) { cout << "concreteElementB被concreteVisitor2访问" << endl; } }; #endif// _CONCRETE_VISITOR_H_
element.h
/************************************************************************ * description: 定义一个accept操作,它以一个访问者为参数 * remark: ************************************************************************/ #ifndef _ELEMENT_H_ #define _ELEMENT_H_ class visitor; class element { public: element(){}; virtual ~element(){}; virtual void accept(visitor* pVisitor) = 0; }; #endif// _ELEMENT_H_
concreteElement.h
#ifndef _CONCRETE_ELEMENT_H_ #define _CONCRETE_ELEMENT_H_ #include "element.h" #include <iostream> using namespace std; class concreteElementA : public element { public: concreteElementA(){}; ~concreteElementA(){}; // 充分利用双分派技术,实现处理与数据结构的分离 virtual void accept(visitor* pVisitor) { if (NULL != pVisitor) { pVisitor->visitConcreteElementA(this); } } // 其他的相关方法 void operationA() { cout << "具体元素A的其他相关方法" << endl; } }; class concreteElementB : public element { public: concreteElementB(){}; ~concreteElementB(){}; // 充分利用双分派技术,实现处理与数据结构的分离 virtual void accept(visitor* pVisitor) { if (NULL != pVisitor) { pVisitor->visitConcreteElementB(this); } } // 其他的相关方法 void operationB() { cout << "具体元素B的其他相关方法" << endl; } }; #endif// _CONCRETE_ELEMENT_H_
objectStructure.h
/************************************************************************ * description: 枚举元素,可以提供一个高层的接口以允许访问者访问它的元素 * remark: ************************************************************************/ #ifndef _OBJECT_STRUCTURE_H_ #define _OBJECT_STRUCTURE_H_ #include "element.h" #include "visitor.h" #include <list> using namespace std; class objectStructure { public: void attach(element* pElement) { m_list.push_back(pElement); } void detach(element* pElement) { m_list.remove(pElement); } void accept(visitor* pVisitor) { list<element*>::iterator Iter; for (Iter = m_list.begin(); Iter != m_list.end(); ++Iter) { if (NULL != *Iter) { (*Iter)->accept(pVisitor); } } } private: list<element*> m_list; }; #endif// _OBJECT_STRUCTURE_H_
客户端
visitorApp.cpp
// visitorApp.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "objectStructure.h" #include "concreteElement.h" #include "concreteVisitor.h" void freePtr(void* vptr) { if (NULL != vptr) { delete vptr; vptr = NULL; } } int _tmain(int argc, _TCHAR* argv[]) { objectStructure* pObject = new objectStructure(); if (NULL != pObject) { element* pElementA = new concreteElementA(); element* pElementB = new concreteElementB(); pObject->attach(pElementA); pObject->attach(pElementB); concreteVisitor1* pVisitor1 = NULL; pVisitor1 = new concreteVisitor1(); concreteVisitor2* pVisitor2 = NULL; pVisitor2 = new concreteVisitor2(); pObject->accept(pVisitor1); pObject->accept(pVisitor2); system("pause"); freePtr(pVisitor2); freePtr(pVisitor1); freePtr(pElementB); freePtr(pElementA); freePtr(pObject); } return 0; }
使用访问者模式的优点和缺点
访问者模式有如下的优点:
访问者模式有如下的缺点:
访问者模式的适用场景:
本文向大家介绍Android编程设计模式之访问者模式详解,包括了Android编程设计模式之访问者模式详解的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Android编程设计模式之访问者模式。分享给大家供大家参考,具体如下: 一、介绍 访问者模式是一种将数据操作与数据结构分离的设计模式,它是《设计模式》中23种设计模式中最复杂的一个,但它的使用频率并不高,正如《设计模式》的作者GOF对访
本文向大家介绍详解设计模式中的中介者模式在C++编程中的运用,包括了详解设计模式中的中介者模式在C++编程中的运用的使用技巧和注意事项,需要的朋友参考一下 作用:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。 结构图如下: Colleage抽象同事类,而ConcreteColleage是具体同时类,每个具体同事只知道自
本文向大家介绍JAVA设计模式之访问者模式详解,包括了JAVA设计模式之访问者模式详解的使用技巧和注意事项,需要的朋友参考一下 在阎宏博士的《JAVA与模式》一书中开头是这样描述访问者(Visitor)模式的: 访问者模式是对象的行为模式。访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变。 分派的概念 变量被声明时的
本文向大家介绍Android编程设计模式之中介者模式详解,包括了Android编程设计模式之中介者模式详解的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Android编程设计模式之中介者模式。分享给大家供大家参考,具体如下: 一、介绍 中介者模式(Mediator Pattern)也称为调解者模式或调停者模式,Mediator本身就有调停者和调解者的意思。 在日常生活中调停者或调解者这个
本文向大家介绍详解Ruby设计模式编程中对单例模式的运用,包括了详解Ruby设计模式编程中对单例模式的运用的使用技巧和注意事项,需要的朋友参考一下 简介 单例模式是设计模式中最简单的形式之一。这一模式的目的是使得类的一个对象成为系统中的唯一实例。要实现这一点,可以从客户端对其进行实例化开始。因此需要用一种只允许生成对象类的唯一实例的机制,“阻止”所有想要生成对象的访问。使用工厂方法来限
本文向大家介绍详解Python设计模式编程中观察者模式与策略模式的运用,包括了详解Python设计模式编程中观察者模式与策略模式的运用的使用技巧和注意事项,需要的朋友参考一下 观察者模式 观察者模式:又叫发布订阅模式,定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时,会通知所有观察者对象,是他们能自动更新自己。 代码结构 众多MQ中间件都是采用这种模