GoF23种设计模式之行为型模式之访问者模式
表示一个作用于某对象结构中的各元素的操作。
它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
适用性
1.一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。
2.需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作“污染”这些对象的类。
Visitor使得你可以将相关的操作集中起来定义在一个类中。
当该对象结构被很多应用共享时,用Visitor模式让每个应用仅包含需要用到的操作。
3.定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。
改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。
如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。
参与者
1.Visitor
为该对象结构中ConcreteElement的每一个类声明一个Visit操作。
该操作的名字和特征标识了发送Visit请求给该访问者的那个类。
这使得访问者可以确定正被访问元素的具体的类。
这样访问者就可以通过该元素的特定接口直接访问它。 2.ConcreteVisitor
实现每个由Visitor声明的操作。
每个操作实现本算法的一部分,而该算法片断乃是对应于结构中对象的类。
ConcreteVisitor为该算法提供了上下文并存储它的局部状态。
这一状态常常在遍历该结构的过程中累积结果。 3.Element
定义一个Accept操作,它以一个访问者为参数。 4.ConcreteElement
实现Accept操作,该操作以一个访问者为参数。 5.ObjectStructure
能枚举它的元素。
可以提供一个高层的接口以允许该访问者访问它的元素。
可以是一个复合或是一个集合,如一个列表或一个无序集合。
类图
例子
public interface Visitor {
public void visitString(StringElement stringE);
public void visitFloat(FloatElement floatE);
public void visitCollection(Collection collection);
}
public class ConcreteVisitor implements Visitor {
public void visitCollection(Collection collection) {
// TODO Auto-generated method stub
Iterator iterator = collection.iterator();
while (iterator.hasNext()) {
Object o = iterator.next();
if (o instanceof Visitable) {
((Visitable)o).accept(this);
}
}
}
public void visitFloat(FloatElement floatE) {
System.out.println(floatE.getFe());
}
public void visitString(StringElement stringE) {
System.out.println(stringE.getSe());
}
}
public interface Visitable {
public void accept(Visitor visitor);
}
public class FloatElement implements Visitable {
private Float fe;
public FloatElement(Float fe) {
this.fe = fe;
}
public Float getFe() {
return this.fe;
}
public void accept(Visitor visitor) {
visitor.visitFloat(this);
}
}
public class StringElement implements Visitable {
private String se;
public StringElement(String se) {
this.se = se;
}
public String getSe() {
return this.se;
}
public void accept(Visitor visitor) {
visitor.visitString(this);
}
}
public class Test {
public static void main(String[] args) {
Visitor visitor = new ConcreteVisitor();
StringElement se = new StringElement("abc");
se.accept(visitor);
FloatElement fe = new FloatElement(new Float(1.5));
fe.accept(visitor);
System.out.println("===========");
List result = new ArrayList();
result.add(new StringElement("abc"));
result.add(new StringElement("abc"));
result.add(new StringElement("abc"));
result.add(new FloatElement(new Float(1.5)));
result.add(new FloatElement(new Float(1.5)));
result.add(new FloatElement(new Float(1.5)));
visitor.visitCollection(result);
}
}
abc
1.5
===========
abc
abc
abc
1.5
1.5
1.5
GoF23种设计模式之行为型模式之访问者模式的更多相关文章
- GoF23种设计模式之行为型模式之状态模式
一.概述 定义对象之间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 二.适用性 1.一个对象的行为取决于它的状态,并且它必须在运行时刻 ...
- GoF23种设计模式之行为型模式之策略模式
传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229 1概述 定义一系列算法,把它们一个个都封装起来,并且让它们可以相互 ...
- GoF23种设计模式之创建型模式之原型模式
一.概述 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 二.适用性 1.当一个系统应该独立于它的产品创建.构成和表示的时候. 2.当要实例化的类是在运行时刻指定的时候,例如:通过动 ...
- GoF23种设计模式之行为型模式之迭代器模式
一.概述 给定一种语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子.二.适用性1.当访问一个聚合对象的内容而无需暴露它的内部表示的时候.2.当对聚合对象的多 ...
- GoF23种设计模式之行为型模式之解释器模式
一.概述 给定一种语言和其文法的一种表示,再定义一个解释器,该解释器使用表示来解释语言中的句子. 二.适用性 当需要解释一种语言,并且可以将该语言中的句子表示 ...
- GoF23种设计模式之行为型模式之观察者模式
一.概述 定义对象之间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新.二.适用性1.当一个抽象模型有两个方面,其中一个方面依赖于另一方面的时 ...
- GoF23种设计模式之创建型模式之工厂方法模式
一.概述 定义一个用于创建对象的接口,让子类去决定实例化哪个类.工厂方法将一个类的实例化延迟至其子类. 二.适用性 1.当一个类不知道它所必须创建的对象的类的时候. 2.当一个类希望由其子类来指定它所 ...
- GoF23种设计模式之创建型模式之抽象工厂模式
一.概述 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 二.适用性 1.一个系统要独立于它的产品的创建.组合和表示的时候. 2.一个系统要由多个产品系列中的一个来配置的时候. ...
- GoF23种设计模式之创建型模式之建造者模式
一.概述 将一个复杂对象的构建与其表示分离开来,使得同样的构建过程可以创建不同的表示. 二.适用性 1.当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式的时候. 2.当构造过程必须允许 ...
随机推荐
- HDU-2586-How far away(LCA Tarjan离线算法)
链接:https://vjudge.net/problem/HDU-2586 题意: 勇气小镇是一个有着n个房屋的小镇,为什么把它叫做勇气小镇呢,这个故事就要从勇气小镇成立的那天说起了,修建小镇的时候 ...
- BZOJ-3555:企鹅QQ(字符串哈希)
PenguinQQ是中国最大.最具影响力的SNS(Social Networking Services)网站,以实名制为基础,为用户提供日志.群.即时通讯.相册.集市等丰富强大的互联网功能体验,满足用 ...
- Netty(6)关闭
客户端: public static void main(String[] args) throws Exception { final SslContext sslCtx; if (SSL) { ...
- python 6 循环
循环 要计算1+2+3,我们可以直接写表达式: >>> 1 + 2 + 3 6 要计算1+2+3+...+10,勉强也能写出来. 但是,要计算1+2+3+...+10000,直接写表 ...
- Java8中的新特性Optional
Optional 类是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象.Optional 是个容器:它可以保存类型T的值,或者仅仅保存 ...
- tyvj P4879骰子游戏-美国70分
需要FFT优化... #include<iostream> #include<cstdio> #include<queue> #include<vector& ...
- 老生常谈Java虚拟机垃圾回收机制(必看篇)
二.垃圾收集 垃圾收集主要是针对堆和方法区进行. 程序计数器.虚拟机栈和本地方法栈这三个区域属于线程私有的,只存在于线程的生命周期内,线程结束之后也会消失,因此不需要对这三个区域进行垃圾回收. 判断一 ...
- 常用API(正则表达式、Date、DateFormat、Calendar)
常用API 今日内容介绍 u 正则表达式 u Date u DateFormat u Calendar 第1章 正则表达式 1.1 正则表达式的概念 正则表达式(英语:Regular Expressi ...
- 【Unity3D】射箭打靶游戏(简单工厂+物理引擎编程)
打靶游戏: 1.靶对象为 5 环,按环计分: 2.箭对象,射中后要插在靶上: 3.游戏仅一轮,无限 trials: 增强要求: 添加一个风向和强度标志,提高难度 游戏成品图: U ...
- 对fgets末尾'\0'的处理
之所以要对fgets自动添加的字符进行处理的原因之一是:当你想比较输入的字符时,你会发现输入的字符和源码用来进行对比的字符一模一样,但是使用strcmp比较时就是不一样,原因就是fgets对输入字符添 ...