设计模式:访问者模式(Visitor)
2016-04-26 19:29
681 查看
定义与结构
访问者模式,顾名思义使用了这个模式后就可以在不修改已有程序结构的前提下,通过添加额外的“访问者”来完成对已有代码功能的提升。《设计模式》一书对于访问者模式给出的定义为:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。从定义可以看出结构对象是使用访问者模式必须条件,而且这个结构对象必须存在遍历自身各个对象的方法。这便类似于java 中的collection 概念了。以下是访问者模式的组成结构:
1) 访问者角色(Visitor):为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色。这样访问者就可以通过该元素角色的特定接口直接访问它。
2) 具体访问者角色(Concrete Visitor):实现每个由访问者角色(Visitor)声明的操作。
3) 元素角色(Element):定义一个Accept 操作,它以一个访问者为参数。
4) 具体元素角色(Concrete Element):实现由元素角色提供的Accept 操作。
5) 对象结构角色(Object Structure):这是使用访问者模式必备的角色。它要具备以下特征:能枚举它的元素;可以提供一个高层的接口以允许该访问者访问它的元素;可以是一个复合(组合模式)或是一个集合,如一个列表或一个无序集合。
类图
访问者模式的实现
//访问者角色--Visitor public interface Visitor { void visit(Gladiolus g); void visit(Runuculus r); void visit(Chrysanthemum c); } //具体访问者角色--Concrete Visitor1 public class StringVal implements Visitor{ String s; public String toString() { return s; } @Override public void visit(Gladiolus g) { // TODO Auto-generated method stub s="Gladiolus"; } @Override public void visit(Runuculus r) { // TODO Auto-generated method stub s="Runuculus"; } @Override public void visit(Chrysanthemum c) { // TODO Auto-generated method stub s="Chrysanthemum"; } } //具体访问者角色--Concrete Visitor2 public class Bee implements Visitor{ @Override public void visit(Gladiolus g) { // TODO Auto-generated method stub System.out.println("Bee and Gladiolus"); } @Override public void visit(Runuculus r) { // TODO Auto-generated method stub System.out.println("Bee and Runuculus"); } @Override public void visit(Chrysanthemum c) { // TODO Auto-generated method stub System.out.println("Bee and Chrysanthemum"); } } //元素角色--Element public interface Flower { void accept(Visitor v); } //具体元素角色--Concrete Element1 public class Runuculus implements Flower{ @Override public void accept(Visitor v) { // TODO Auto-generated method stub v.visit(this); } } //具体元素角色--Concrete Element2 public class Gladiolus implements Flower{ @Override public void accept(Visitor v) { // TODO Auto-generated method stub v.visit(this); } } //具体元素角色--Concrete Element3 public class Chrysanthemum implements Flower{ @Override public void accept(Visitor v) { // TODO Auto-generated method stub v.visit(this); } } //对象结构角色--Object Structure //这是一个对象生成器,不是一个完整的对象结构,这里仅仅是模拟对象结构中的元素 public 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 { 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[]) { BeeAndFlowers test=new BeeAndFlowers(); test.test(); } }
验证输出
Gladiolus Runuculus Runuculus Gladiolus Gladiolus Runuculus Runuculus Chrysanthemum Chrysanthemum Runuculus
总结
使用了访问者模式以后,对于原来的类层次增加新的操作,仅仅需要实现一个具体访问者角色就可以了,而不必修改整个类层次。而且这样符合“开闭原则”的要求。而且每个具体的访问者角色都对应于一个相关操作,因此如果一个操作的需求有变,那么仅仅修改一个具体访问者角色,而不用改动整个类层次。相关文章推荐
- BZOJ1179: [Apio2009]Atm
- 超客车,行驶学校路段
- span问题
- POJ 2739 Sum of Consecutive Prime Numbers(Two pointers)
- Java虚拟机如何加载Class文件
- HDU 1495 - 非常可乐
- python遍历数组的两种方法
- ZOJ 3936-Apples and Ideas【模拟】(2016浙江省大学生程序设计竞赛)
- 【GDOI2016模拟4.23】无界单词
- C++实验4
- Python 内置函数 range的使用
- CSS3动画工具
- 递归算法 笔记
- MATLAB——scatter的简单应用
- java中四种操作(dom、sax、jdom、dom4j)xml方式详解与比较
- 关于工作流后台流程并行程序的有用信息
- error: zlib.h:no such file or directory
- 【Nginx】下载,请求限流限速,根据URL参数限速
- Android技术知识分享第一弹——SDK中常用命令
- 【Nginx】下载,请求限速,根据URL参数限速