设计模式之二十四:訪问者模式(Visitor)
訪问者模式:
定义了一个作用于一个类的一些操作,訪问者模式同意在不改变类的前提下添加一些操作。
Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.
UML类图:
主要包括:
- Visitor:声明了一个全部訪问器都须要实现的接口。
- ConcreteVisitor:实现每一个訪问器都须要实现的接口,每一个操作知识实现了和特定类相关的一些算法。
- Element:定义了一个须要接受Visitor作为參数的accept方法。
- ConcreteElement:实现了accept方法的类。
- ObjectStructure:包括全部的Element对象,提供了一个高层次的接口同意visitor訪问elements元素。
这个模式主要使用在须要给类加入一个功能,可是不希望在类中加入时使用。C++代码实现:
#include <iostream>
#include <list>
using namespace std;
class ConcreteElementA;
class ConcreteElementB;
class Visitor
{
public:
virtual void visitConcreteElementA(ConcreteElementA * c)=0;
virtual void visitConcreteElementB(ConcreteElementB *)=0;
};
class ConcreteVisitor1:public Visitor
{
public:
virtual void visitConcreteElementA(ConcreteElementA * c)
{
cout<<"ConcreteVisit1 operate on ConcreteElementA"<<endl;
}
virtual void visitConcreteElementB(ConcreteElementB *)
{
cout<<"ConcreteVisitor1 operate on ConcreteElementB"<<endl;
}
};
class ConcreteVisitor2:public Visitor
{
public:
virtual void visitConcreteElementA(ConcreteElementA * c)
{
cout<<"ConcreteVisit2 operate on ConcreteElementA"<<endl;
}
virtual void visitConcreteElementB(ConcreteElementB *)
{
cout<<"ConcreteVisitor2 operate on ConcreteElementB"<<endl;
}
};
class Element
{
public:
virtual void accept(Visitor * visitor)=0;
};
class ConcreteElementA:public Element
{
public:
void accept(Visitor * visitor)
{
visitor->visitConcreteElementA(this);
}
};
class ConcreteElementB:public Element
{
public:
void accept(Visitor * visitor)
{
visitor->visitConcreteElementB(this);
}
};
class ObjectStructure
{
public:
void attach(Element *e)
{
elements.push_back(e);
}
void detach(Element *e)
{
elements.remove(e);
}
void accept(Visitor * v)
{
list<Element *>::iterator iter;
for(iter=elements.begin();iter!=elements.end();iter++)
{
(*iter)->accept(v);
}
}
private:
list<Element *> elements;
};
int main()
{
ObjectStructure * o=new ObjectStructure();
Element * a=new ConcreteElementA();
Element * b=new ConcreteElementB();
o->attach(a);
o->attach(b);
Visitor * v1=new ConcreteVisitor1();
Visitor *v2=new ConcreteVisitor2();
o->accept(v1);
o->accept(v2);
delete o;
delete a;
delete b;
delete v1;
delete v2;
}
运行输出:
设计模式之二十四:訪问者模式(Visitor)的更多相关文章
- 设计模式(二十四)——职责链模式(SpringMVC源码分析)
1 学校 OA 系统的采购审批项目:需求是 采购员采购教学器材 1) 如果金额 小于等于 5000, 由教学主任审批 (0<=x<=5000) 2) 如果金额 小于等于 10000, ...
- 设计模式之十五:訪问者模式(Visitor Pattern)
訪问者模式(Visitor Pattern)是GoF提出的23种设计模式中的一种,属于行为模式. 据<大话设计模式>中说算是最复杂也是最难以理解的一种模式了. 定义(源于GoF<De ...
- 设计模式入门之訪问者模式Visitor
//訪问者模式定义:表示一个作用于某对象结构中的各个元素的操作,它使你能够在不改变各元素类的前提下定义作用于这些元素的新操作. //从定义上看.这个模式跟装饰模式的定义非常类似(动态地给一个对象加入一 ...
- ASP.NET Core 3.0 : 二十四. 配置的Options模式
上一章讲到了配置的用法及内部处理机制,对于配置,ASP.NET Core还提供了一种Options模式.(ASP.NET Core 系列目录) 一.Options的使用 上一章有个配置的绑定的例子,可 ...
- 设计模式之(十四)责任链模式(Chain of Responsibility)
在业务场景中,有很多是需要审批的.审核方式还可能常常发生变化,而责任链模式就是为了解决这种场景的情况的. 责任链模式定义:十多个对象都有机会处理请求,从而避免发送者和接受者之间的耦合关系.讲这些对象连 ...
- 设计模式学习(二十四):Spring 中使用到的设计模式
设计模式学习(二十四):Spring 中使用到的设计模式 作者:Grey 原文地址: 博客园:设计模式学习(二十四):Spring 中使用到的设计模式 CSDN:设计模式学习(二十四):Spring ...
- JAVA设计模式之 訪问者模式【Visitor Pattern】
一.概述 訪问者模式是一种较为复杂的行为型设计模式,它包括訪问者和被訪问元素两个主要组成部分.这些被訪问的元素通常具有不同的类型,且不同的訪问者能够对它们进行不同的訪问操作.在使用訪问者模式时,被訪问 ...
- Java 设计模式系列(十四)命令模式(Command)
Java 设计模式系列(十四)命令模式(Command) 命令模式把一个请求或者操作封装到一个对象中.命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复 ...
- Bootstrap<基础二十四> 缩略图
Bootstrap 缩略图.大多数站点都需要在网格中布局图像.视频.文本等.Bootstrap 通过缩略图为此提供了一种简便的方式.使用 Bootstrap 创建缩略图的步骤如下: 在图像周围添加带有 ...
随机推荐
- File.ReadAllText 读取中文乱码问题
原文:File.ReadAllText 读取中文乱码问题 用 File.ReadAllText(filepath) 去读取中文txt文件会遇到乱码问题,我自己测试了一下,ANSI编码的txt才会出 ...
- 如何让vnc控制由默认的twm界面改为gnome?(转)
其实只要修改用户 .vnc目录下的xstartup配置文件即可 [root@localhost ~]# more /root/.vnc/xstartup#!/bin/sh # Uncomment th ...
- 文艺编程 Literate Programming
(译注:这篇文章是 Donald Knuth 一篇1983年的论文:Literate Programming 的介绍部分.有人翻译为“字面编程”,是极其错误的说法,literate 根本就没有“字面” ...
- linux scp ssh命令不用输入密码
把你的本地主机用户的ssh公匙文件复制到远程主机用户的~/.ssh/authorized_keys文件中 假设本地主机linux100,远程主机linux200 一,在linux100主机里的用户 运 ...
- python图片小爬虫
import re import urllib import os def rename(name): name = name + '.jpg' return name def getHtml(url ...
- Java中的import
有些人写了一阵子 Java,可是对于 Java的 package 跟 import 还是不太了解.很多人以为原始码 .java 文件中的 import 会让编译器把所 import 的程序通通写到编译 ...
- arm+linux 裸机环境搭建之安装工具篇(eclipse)
之前已经讲述如何安装gcc和gdb,在此不赘述! 一.所需要的软件有两个: jre-7u25-linux-i586.rpm(虚拟机) eclipse-cpp-kepler-R-linux-gtk .t ...
- C# 利用反射动态调用类成员
用反射动态调用类成员,需要Type类的一个方法:InvokeMember.对该方法的声明如下(摘抄于MSDN): publicobject InvokeMember( string name, ...
- 事件:target与currentTarget区别
target在事件流的目标阶段:currentTarget在事件流的捕获,目标及冒泡阶段.只有当事件流处在目标阶段的时候,两个的指向才是一样的, 而当处于捕获和冒泡阶段的时候,target指向被单击的 ...
- android: ListView历次优化
第一版: ListView一屏显示多少对象其内部就创建多少View对象.滑动时退出的缓存对象留给滑进去时调用getView传的convertView.因为如果每次都findViewById查找创建视图 ...