设计模式学习笔记(二十)—Visitor访问者模式

Visitor模式定义:

表示一个作用于某对象结构中各元素的操作。它可以使你不修改各元素类的前提下定义作用于这些元素的新操作,也就是动态的增加新的方法。

Visitor模式结构图:

Visitor模式中主要角色:

1)访问者角色(Visitor):为该对象结构(ObjectStructure)中的具体元素提供一个访问操作接口。该操作接口的名字和参数标识了要访问的具体元素角色。这样访问者就可以通过该元素角色的特定接口直接访问它。

2)具体访问者角色(ConcreteVisitor):实现Vistor接口的操作。

3)元素角色(Element):该接口定义一个accept操作接受具体的访问者。

4)具体元素角色(ConcreteElement):实现Element的accept操作。

5)对象结构角色(ObjectStructure):这是使用访问者模式必备的角色。它要具备以下特征:能枚举它的元素;可以提供一个高层的接口以允许该访问者访问它的元素;可以是一个复合(组合模式)或是一个集合,如一个列表或一个无序集合。

Visitor模式的一个例子

由于本人阅历不足,实在想不出好的例子,这个例子基本是按结构图所写,不过已经加上了注释。

import java.util.ArrayList;
import java.util.Collection;

interface Visitor{
public void visitElementA(ConcreteElementA elementA);//针对具体元素A的新方法
public void visitElementB(ConcreteElementB elementB);//针对具体元素B的新方法
}
interface Element{
public void accept(Visitor visitor);
}
class ConcreteVisitor implements Visitor{//具体的访问者

public void visitElementA(ConcreteElementA elementA) {
 System.out.println(elementA.getName()+" visited by ConcreteVisitor ");

}
public void visitElementB(ConcreteElementB elementB) {
 System.out.println(elementB.getName()+" visited by ConcreteVisitor ");

}
}
class ConcreteElementA implements Element{//具体元素A
private String name;
public ConcreteElementA(String name){
 this.name=name;
}

public void accept(Visitor visitor) {//接受访问者调用它针对该元素的新方法
 visitor.visitElementA(this);

}
public String getName() {
 return name;
}
}
class ConcreteElementB implements Element{//具体元素B
private String name;
public ConcreteElementB(String name){
 this.name=name;
}
public String getName() {
 return name;
}
public void accept(Visitor visitor) {//接受访问者调用它针对该元素的新方法
 visitor.visitElementB(this);

}
}
class ObjectStructure{//对象结构即元素的集合
private Collection<Element> collection=new ArrayList<Element>();
public void attach(Element element){
 collection.add(element);
}
public void detach(Element element){
 collection.remove(element);
}
public void accept(Visitor visitor )
  {
   for(Element element:collection){
   element.accept(visitor);
   }
  }

}
public class Client {
public static void main(String args[]){
 Element elementA=new ConcreteElementA("ElementA");
 Element elementB=new ConcreteElementB("ElementB");
 Visitor visitor=new ConcreteVisitor();

 ObjectStructure os=new ObjectStructure();
 os.attach(elementA);
 os.attach(elementB);
 os.accept(visitor);

 }
}

Visitor模式优缺点:

1)优点:不用修改具体的元素类,就可以增加新的操作。主要是通过元素类的accept方法来接受一个visitor对象来实现的。

2) 缺点:不易频繁增加元素类,没增加一个元素类,就要在Visitor接口中写一个针对该元素的方法,而且还要修改Visitor的子类。

时间: 2024-08-28 19:58:58

设计模式学习笔记(二十)—Visitor访问者模式的相关文章

设计模式学习笔记(二十二)—FlyWeight享元模式

一.FlyWeight模式定义: 运用共享技术有效地支持大量细粒度对象. 二.模式解说 也就是说在一个系统中如果有多个相同的对象,那么只共享一份就可以了,不必每个都去实例化一个对象.在Flyweight模式中,由于要产生各种各样的对象,所以在Flyweight(享元)模式中常出现Factory模式.Flyweight的内部状态是用来共享的,Flyweight factory负责维护一个对象存储池(Flyweight Pool)来存放内部状态的对象.Flyweight模式是一个提高程序效率和性能的

kvm虚拟化学习笔记(二十)之convirt安装linux系统

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://koumm.blog.51cto.com/703525/1306526 情况说明: (1)本文接前文kvm虚拟化学习笔记(十九)之convirt集中管理平台搭建,采用convirt虚拟化平台安装linux操作系统的过程,这个过程中需要对convirt进行一系列的配置才能真正的使用convirt来实现管理.(2)convirt2.1.1是一套kvm/xen虚拟机管理工具,该管理工具

设计模式学习笔记(二十一)—Composite模式

今天开始学习Composite模式,首先让我们看一下它的定义: 将对象组合成树形结构以表示"整体-部分"的层次结构.Composite模式使单个对象和组合对象的使用具有一致性. 下面给出这个模式的结构图: 如果把Composite模式看成是树形结构的话,那么它主要角色有: 1)树干角色(Component):该角色是一个抽象类,它定义了一些操作增删树叶(Leaf)的操作. 2)树枝角色(Composite):树枝上有很多树干,树枝也是树干的一种. 3)树叶角色(Leaf):树干上的树叶

设计模式学习笔记(二)—-Adapter适配器模式

GOF<设计模式>一书对Adapter模式是这样描述的: 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使原本由于接口不兼容而不能一起工作的类可以一起工作. 这段话大致是说:我们需要一种方式,为一个功能正确但接口不合的对象创建一个新接口.例如,客户给我们如下需求: 1)为都有"显示"(display)行为的点.线.正方形分别创建类. 2)客户对象不必知道自己到底拥有点.线.还是正方形.它只需知道拥有这些形状中的一个. 也就是说,我们要用一个更高层次的概念将这

JavaScript权威设计--jQuery,Ajax.animate,SVG(简要学习笔记二十)[完结篇]

1.$和jquery在全局命名空间中定义的唯一两个变量.   2.jquery是工厂函数,不是构造函数.他返回一个新创建的对象.   3.jquery的四种调用方式:     <1>传递CSS选择器(字符串)给$()方法       <2>传递Element,Document或Window对象给$()方法       <3>传递HTML文本字符串给$()方法.     如: var img=$("<img/>", //新建一个<im

javascript构造函数: JavaScript学习笔记(二十四) 模块创建构造函

 模块创建构造函数(Modules That Create Constructors)在前面的例子中,创建了一个MYAPP.utilities.array对象,但有时候使用构造函数创建你的对象更方便,你也可以使用模块模式实现它.唯一的不同就是在包裹模块的立即执行函数返回一个函数而不是对象.下面这个例子就是模块模式创建一个构造函数 MYAPP.utilities.ArrayMYAPP.namespace('MYAPP.utilities.Array');MYAPP.utilities.Array

hibernate3学习笔记(二十二)|Query缓存机制

接前面的例子:http://blog.csdn.net/kunshan_shenbin/archive/2008/09/03/2874375.aspx 测试代码如下: 1.package com.hb3.pack_22;2.3.import java.io.IOException;4.import java.sql.SQLException;5.import java.util.List;6. 7.import org.hibernate.Query;8.import org.hibernate

hibernate3学习笔记(二十)|关系映射:多对多

要实现多对多的对应,一般可以借由一个中间表来完成.也就是借由一对多,多对一来完成. DDL: 1.CREATE TABLE user (2. id INT(11) NOT NULL auto_increment PRIMARY KEY,3. name VARCHAR(100) NOT NULL default ''4.);5. 6.CREATE TABLE user_server (7. user_id INT(11),8. server_id INT(11)9.);10. 11.CREATE

javascript学习笔记(二十) 获得和设置元素的特性(属性)_基础知识

本节html以下面的为例 复制代码 代码如下: <div id="myDiv" class="bd" title="我是div"> <img id="img1" /> <a id="myA" href = "http://www.baidu.com">百度</a> </div> 1.通过HTMLElement类型(对象)的属性获