深入浅出Java的访问者模式

一、引子

对于系统中一个已经完成的类层次结构,我们已经给它提供了满足需求的接口。但是面对新增加的需求,我们应该怎么做呢?如果这是为数不多的几次变动,而且你不用为了一个需求的调整而将整个类层次结构统统地修改一遍,那么直接在原有类层次结构上修改也许是个 不错 的主意。

但是往往我们遇到的却是:这样的需求变动也许会不停的发生;更重要的是需求的任何变动可能都要让你将整个类层次结构修改个底朝天……。这种类似的操作分布在不同的类里面,不是一个好现象,我们要对这个结构重构一下了。

那么,访问者模式也许是你很好的选择。

二、定义与结构

访问者模式,顾名思义使用了这个模式后就可以在不修改已有程序结构的前提下,通过添加额外的“访问者”来完成对已有代码功能的提升。

《设计模式》一书对于访问者模式给出的定义为:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。从定义可以看出结构对象是使用访问者模式必须条件,而且这个结构对象必须存在遍历自身各个对象的方法。这便类似于java中的collection概念了。

以下是访问者模式的组成结构:

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

2) 具体访问者角色(Concrete Visitor):实现每个由访问者角色(Visitor)声明的操作。

3) 元素角色(Element):定义一个Accept操作,它以一个访问者为参数。

4) 具体元素角色(Concrete Element):实现由元素角色提供的Accept操作。

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

来张类图就能更加清晰的看清访问者模式的结构了。

那么像引言中假想的。我们应该做些什么才能让访问者模式跑起来呢?首先我们要在原有的类层次结构中添加accept方法。然后将这个类层次中的类放到一个对象结构中去。这样再去创建访问者角色……

三、举例

本人阅历实在可怜,没能找到访问者模式在实际应用中的例子。只好借《Thinking in Patterns with java》中的教学代码一用。我稍微做了下修改。

import java.util.*;
import junit.framework.*;
//访问者角色
interface Visitor {
  void visit(Gladiolus g);
  void visit(Runuculus r);
  void visit(Chrysanthemum c);
}
// The Flower hierarchy cannot be changed:
//元素角色
interface Flower {
  void accept(Visitor v);
}
//以下三个具体元素角色
class Gladiolus implements Flower {
  public void accept(Visitor v) { v.visit(this);}
}
class Runuculus implements Flower {
  public void accept(Visitor v) { v.visit(this);}
}
class Chrysanthemum implements Flower {
  public void accept(Visitor v) { v.visit(this);}
}
// Add the ability to produce a string:
//实现的具体访问者角色
class StringVal implements Visitor {
  String s;
  public String toString() { return s; }
  public void visit(Gladiolus g) {
   s = "Gladiolus";
  }
  public void visit(Runuculus r) {
   s = "Runuculus";
  }
  public void visit(Chrysanthemum c) {
   s = "Chrysanthemum";
  }
}
// Add the ability to do "Bee" activities:
//另一个具体访问者角色
class Bee implements Visitor {
  public void visit(Gladiolus g) {
   System.out.println("Bee and Gladiolus");
  }
  public void visit(Runuculus r) {
   System.out.println("Bee and Runuculus");
  }
  public void visit(Chrysanthemum c) {
   System.out.println("Bee and Chrysanthemum");
  }
}
//这是一个对象生成器
//这不是一个完整的对象结构,这里仅仅是模拟对象结构中的元素
class FlowerGenerator {
  private static Random rand = new Random();
  public static Flower newFlower() {
   switch (rand.nextInt(3)) {
   default:
    case 0: return new Gladiolus(); 
    case 1: return new Runuculus();
    case 2: return new Chrysanthemum();
   }
  }
}
//客户 测试程序
public class BeeAndFlowers extends TestCase {
  /*
   在这里你能看到访问者模式执行的流程:
   首先在客户端先获得一个具体的访问者角色
   遍历对象结构
   对每一个元素调用accept方法,将具体访问者角色传入
   这样就完成了整个过程
  */
  //对象结构角色在这里才 组装 上
  List flowers = new ArrayList();
  public BeeAndFlowers() {
   for(int i = 0; i < 10; i++)
    flowers.add(FlowerGenerator.newFlower());
  }
  Visitor sval ;
  public void test() {
   // It’s almost as if I had a function to
   // produce a Flower string representation:
   //这个地方你可以修改以便使用另外一个具体访问者角色
   sval = new StringVal();
   Iterator it = flowers.iterator();
   while(it.hasNext()) {
    ((Flower)it.next()).accept(sval);
    System.out.println(sval);
   }
  }
  public static void main(String args[]) {
   junit.textui.TestRunner.run(BeeAndFlowers.class);
  }
}

时间: 2024-12-22 03:04:59

深入浅出Java的访问者模式的相关文章

Java设计模式--访问者模式

访问者模式(别名:虚拟构造) 表示一个作用于某对象结构中的各个元素的操作.它可以在不改变各个元素的类的前提下定义作用于这些元素的新操作. Visitor Pattern Represent an operation to be preformed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements o

详解Java设计模式编程中的访问者模式_java

定义:封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作.类型:行为类模式类图: 例子:例如,思考一下添加不同类型商品的购物车,当点击结算的时候,它计算出所有不同商品需付的费用.现在,计算逻辑即为计算这些不同类型商品的价格.或者说通过访问者模式我们把此逻辑转移到了另外一个类上面.让我们实现这个访问者模式的例子. 为了实现访问者模式,最先需要做的是创建能够被添加到购物车中代表不同类型商品(itemElement)的类. ItemElement.ja

Java设计模式(二十一)----访问者模式

访问者模式 一.概述 1.定义 2.分派的概念 3.分派的类型 4.双重分派 二.结构 三.具体案例 一.概述 1.定义 访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变. 2.分派的概念 变量被声明时的类型叫做变量的静态类型(Static Type),有些人又把静态类型叫做明显类型(Apparent Type):而变量所引用的对象的真实类型又叫做变量的实际类型(Actual Type).比如: List list = n

举例讲解设计模式中的访问者模式在Java编程中的运用_java

访问者(Visitor)模式:封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作.访问者模式的结构图如下: 通过上图可以看到他有如下角色:抽象访问者(Visitor)角色:定义接口,声明一个或多个访问操作. 具体访问者(ConcreteVisitor)角色:实现抽象访问者所声明的接口,也就是抽象访问者所声明的各个访问操作. 抽象元素(Visitable)角色:声明一个接受操作,接受一个访问者对象作为一个参数. 具体元素结点(Concrete

JAVA设计模式之访问者模式详解_java

在阎宏博士的<JAVA与模式>一书中开头是这样描述访问者(Visitor)模式的: 访问者模式是对象的行为模式.访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变. 分派的概念 变量被声明时的类型叫做变量的静态类型(Static Type),有些人又把静态类型叫做明显类型(Apparent Type):而变量所引用的对象的真实类型又叫做变量的实际类型(Actual Type).比如: 复制代码 代码如下: List lis

java中的访问者模式 – 例子辅导

原文链接 作者:Pankaj Kumar 译者:f0tlo <1357654289@qq.com> 访问者模式是一种行为设计模式.访问者模式被用在针对一组相同类型对象的操作.优点是,可以把针对此对象的操作逻辑转移到另外一个类上. 例如,思考一下添加不同类型商品的购物车,当点击结算的时候,它计算出所有不同商品需付的费用.现在,计算逻辑即为计算这些不同类型商品的价格.或者说通过访问者模式我们把此逻辑转移到了另外一个类上面.让我们实现这个访问者模式的例子. 为了实现访问者模式,最先需要做的是创建能够

设计模式之访问者模式

        刚刚学完设计模式的访问者模式(编译器模式),这里就对该模式进行了总结与分析. 一.产生原因         这里存在一个这样的问题:如果某系统已经完成了一个类层次并提供了满足需求的所有接口,现在要增加新的需求,我们需要怎么做?         可能你会采用增加该需求并把整个层次结构统统修改一遍.然而如果需求变动会不停的发生,而且需求的任何变动都会让整个结构统统修改一遍,此时你会怎么做呢?        所以,我们现在需要对这个系统结构进行重构,访问者模式也许就是你解决上面问题最好

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

Visitor模式定义: 表示一个作用于某对象结构中各元素的操作.它可以使你不修改各元素类的前提下定义作用于这些元素的新操作,也就是动态的增加新的方法. Visitor模式结构图: Visitor模式中主要角色: 1)访问者角色(Visitor):为该对象结构(ObjectStructure)中的具体元素提供一个访问操作接口.该操作接口的名字和参数标识了要访问的具体元素角色.这样访问者就可以通过该元素角色的特定接口直接访问它. 2)具体访问者角色(ConcreteVisitor):实现Visto

设计模式之四:访问者模式

目录介绍 1.访问者模式介绍 2.访问者模式定义 3.访问者模式UML图 4.访问者模式简单案例 5.访问者模式之Android源码分析 5.1 注解简单介绍 5.2 注解与访问者模式关系 5.3 注解与性能的关系 6.访问者模式之实践 6.1 介绍 6.2 编译期注解之ButterKnife 6.3 编译期注解之Dagger2 6.4 自己写个简单支持View的ID注入的工具 6.4.0 基本逻辑思路 7.注解之ButterKnife源码分析 7.0 简单工作流程 7.1 首先看看Bind注解