一句话

表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

概括

解析

情人节到了,要给每个MM送一束鲜花和一张卡片,可是每个MM送的花都要针对她个人的特点,每张卡片也要根据个人的特点来挑,我一个人哪搞得清楚,还是找花店老板和礼品店老板做一下Visitor,让花店老板根据MM的特点选一束花,让礼品店老板也根据每个人特点选一张卡,这样就轻松多了;

访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构可以保持不变。访问者模式适用于数据结构相对未定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化。访问者模式使得增加新的操作变的很容易,就是增加一个新的访问者类。访问者模式将有关的行为集中到一个访问者对象中,而不是分散到一个个的节点类中。当使用访问者模式时,要将尽可能多的对象浏览逻辑放在访问者类中,而不是放到它的子类中。访问者模式可以跨过几个类的等级结构访问属于不同的等级结构的成员类。

实例

还是以产品的开发为例,

产品开发分为 硬件和软件两部分。

对应的有 HardwareProduct 和 SoftwareProduct 两个类, 但是现在需要提升原有类的功能, 但是又不想改动到原有的结构,所以就添加额外的“访问者” 来提升功能。

代码列表:

IVisitor.java   - 访问者接口

HardwareProduct.java  具体访问者

IVisitable.java - 元素接口

HardwareProduct.java  - 具体元素

SoftwareProduct.java - 具体元素

TestMain.java - 测试主类

package designptn.vistor;

public interface IVisitor {
	public void visitSoftware(SoftwareProduct product);

	public void visitHardware(HardwareProduct product);
}

package designptn.vistor;

import java.util.Collection;
import java.util.Iterator;

public class ConcreteVisitor implements IVisitor {

	@Override
	public void visitSoftware(SoftwareProduct product) {
		// TODO Auto-generated method stub
		System.out.println(product.getProductName());
	}

	@Override
	public void visitHardware(HardwareProduct product) {
		// TODO Auto-generated method stub
		System.out.println(product.getProductName());
	}

}

package designptn.vistor;

public interface IVisitable {
	public void accept(IVisitor visitor);
}

/**
 * @author oscar999
 * @date 2013-7-17
 * @version V1.0
 */
package designptn.vistor;

public class HardwareProduct implements IVisitable {
	private String productName;

	public HardwareProduct(String productName){
		this.productName = productName;
	}

	public String getProductName() {
		return productName;
	}

	public void setProductName(String productName) {
		this.productName = productName;
	}

	@Override
	public void accept(IVisitor visitor) {
		// TODO Auto-generated method stub
		visitor.visitHardware(this);
	}

}
/**
 * @author oscar999
 * @date 2013-7-17
 * @version V1.0
 */
package designptn.vistor;

public class SoftwareProduct implements IVisitable {

	private String productName;

	public SoftwareProduct(String productName){
		this.productName = productName;
	}

	public String getProductName() {
		return productName;
	}

	public void setProductName(String productName) {
		this.productName = productName;
	}

	@Override
	public void accept(IVisitor visitor) {
		// TODO Auto-generated method stub
		visitor.visitSoftware(this);
	}
}
package designptn.vistor;

public class TestMain {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		IVisitor visitor = new ConcreteVisitor();
		HardwareProduct hardProduct = new HardwareProduct("hard 1");
		hardProduct.accept(visitor);

		SoftwareProduct softProduct = new SoftwareProduct("soft 1");
		softProduct.accept(visitor);
	}

}

再增加上对象结构角色

修改ConcreteVisitor.java  和TestMain.java

package designptn.vistor;

import java.util.Iterator;
import java.util.List;

public class ConcreteVisitor implements IVisitor {

	@SuppressWarnings("rawtypes")
	public void visitProducts(List<IVisitable> list) {
		Iterator iterator = list.iterator();
		while (iterator.hasNext()) {
			Object o = iterator.next();
			if (o instanceof IVisitable) {
				((IVisitable) o).accept(this);
			}
		}
	}

	@Override
	public void visitSoftware(SoftwareProduct product) {
		// TODO Auto-generated method stub
		System.out.println(product.getProductName());
	}

	@Override
	public void visitHardware(HardwareProduct product) {
		// TODO Auto-generated method stub
		System.out.println(product.getProductName());
	}

}

package designptn.vistor;

import java.util.ArrayList;
import java.util.List;

public class TestMain {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ConcreteVisitor visitor = new ConcreteVisitor();
		HardwareProduct hardProduct = new HardwareProduct("hard 1");
		hardProduct.accept(visitor);

		SoftwareProduct softProduct = new SoftwareProduct("soft 1");
		softProduct.accept(visitor);

		System.out.println("--------------------------");
		List<IVisitable> list = new ArrayList<IVisitable>();
		list.add(new HardwareProduct("hard 2"));
		list.add(new HardwareProduct("hard 3"));

		list.add(new SoftwareProduct("soft 2"));
		list.add(new SoftwareProduct("soft 3"));
		visitor.visitProducts(list);
	}

}

[设计模式-行为型]访问者模式(Vistor)的更多相关文章

  1. 设计模式 ( 二十 ) 访问者模式Visitor(对象行为型)

    设计模式 ( 二十 ) 访问者模式Visitor(对象行为型) 1.概述 在软件开发过程中,对于系统中的某些对象,它们存储在同一个集合collection中,且具有不同的类型,而且对于该集合中的对象, ...

  2. Java 设计模式系列(二三)访问者模式(Vistor)

    Java 设计模式系列(二三)访问者模式(Vistor) 访问者模式是对象的行为模式.访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以 ...

  3. 重学 Java 设计模式:实战访问者模式「模拟家长与校长,对学生和老师的不同视角信息的访问场景」

    作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 能力,是你前行的最大保障 年龄会不断的增长,但是什么才能让你不 ...

  4. 设计模式学习之访问者模式(Visitor,行为型模式)(21)

    参考:https://www.cnblogs.com/edisonchou/p/7247990.html 在患者就医时,医生会根据病情开具处方单,很多医院都会存在以下这个流程:划价人员拿到处方单之后根 ...

  5. Java进阶篇设计模式之十 ---- 访问者模式和中介者模式

    前言 在上一篇中我们学习了行为型模式的解释器模式(Interpreter Pattern)和迭代器模式(Iterator Pattern).本篇则来学习下行为型模式的两个模式,访问者模式(Visito ...

  6. Java设计模式之十 ---- 访问者模式和中介者模式

    前言 2018年已经过去,新的一年工作已经开始,继续总结和学习Java设计模式. 在上一篇中我们学习了行为型模式的解释器模式(Interpreter Pattern)和迭代器模式(Iterator P ...

  7. 22.访问者模式(Vistor Pattern)

    using System; using System.Collections; namespace ConsoleApplication5 { /// <summary> /// 访问者模 ...

  8. 设计模式のVisitorPattern(访问者模式)----行为模式

    一.产生背景 访问者模式是封装一些施加于某种数据结构之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以保存不变.访问者模式适用于数据结构相对稳定的系统, 它把数据结构和作用于数据结构之 ...

  9. 《JAVA设计模式》之访问者模式(Visitor)

    在阎宏博士的<JAVA与模式>一书中开头是这样描述访问者(Visitor)模式的: 访问者模式是对象的行为模式.访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要 ...

随机推荐

  1. linux学习(一)——学习之路

    首先,要学Linux编程,你得会用Linux,也就是得在命令行环境下生存下来.什么叫生存下来呢?就是我现在给你一台主机,键盘,显示器啥的,然后给你一个服务器版的Linux系统的光盘或者其他什么安装盘, ...

  2. cocos2d-x 显示中文字符和解析XML文件 转载

    源地址:http://codingnow.cn/cocos2d-x/1038.html 在cocos2d-x中直接显示中文的时候会出现乱码,虽然在实际开发中把字符串直接写在代码里也不是好的做法,但是有 ...

  3. Mac下安装OpenCV问题

    最近看了纹理特征方面的paper,看了一些资料之后,想要实际动手实现一下其中LBP算法,果然OpenCV中已经实现. 问题 No module named "cv2" 当我在我们项 ...

  4. lintcode-86-二叉查找树迭代器

    86-二叉查找树迭代器 设计实现一个带有下列属性的二叉查找树的迭代器: 元素按照递增的顺序被访问(比如中序遍历) next()和hasNext()的询问操作要求均摊时间复杂度是O(1) 样例 对于下列 ...

  5. WebSocket API使用篇检测浏览器是否支持WebSocket(4)

    WebSocket API是下一代客户端-服务器的异步通信方法.前面有三篇文章已经对WebSocket有了一些介绍,这里我总结了一下.我在使用WebSockets API过程中遇到的问题. 1.检测浏 ...

  6. BZOJ5109 CodePlus 2017大吉大利,晚上吃鸡!(最短路+拓扑排序+bitset)

    首先跑正反两遍dij求由起点/终点到某点的最短路条数,这样条件一就转化为f(S,A)*f(T,A)+f(S,B)*f(T,B)=f(S,T).同时建出最短路DAG,这样图中任何一条S到T的路径都是最短 ...

  7. BZOJ4668 冷战(并查集)

    显然可以用LCT维护kruskal重构树.或者启发式合并维护kruskal重构树的倍增数组虽然多了个log也不一定比LCT慢吧. 当然这里的kruskal重构树几乎只是把树上的边权换成了点权,并不重要 ...

  8. [POJ1784]Huffman's Greed

    题面在这里 题意 给出一棵\(n\)个节点的二叉查找树的中序遍历中每个节点的访问次数\(p[i]\),和相邻两节点\(i\)和\(i+1\)的访问次数\(q[i]\),构造一棵二叉查找树使得\(\su ...

  9. [链接] Linux下常见的~/.bashrc、/etc/profile、/etc/ld.so.config小科普以及caffe编译遇到的相关问题解决

    由于博主设置禁止转载,这里贴一个链接,http://blog.csdn.net/u014266895/article/details/61928602,内容很有用,linux下很多软件问题都是各种路径 ...

  10. JSOI2004 平衡点 / 吊打XXX [模拟退火]

    题目描述 如图:有n个重物,每个重物系在一条足够长的绳子上.每条绳子自上而下穿过桌面上的洞,然后系在一起.图中X处就是公共的绳结.假设绳子是完全弹性的(不会造成能量损失),桌子足够高(因而重物不会垂到 ...