一句话

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

概括

解析

情人节到了,要给每个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. URAL 1936 Roshambo(求期望)

    Description Bootstrap: Wondering how it's played? Will: It's a game of deception. But your bet inclu ...

  2. 搭建Elasticsearch 5.4分布式集群

    多机集群中的节点可以分为master nodes和data nodes,在配置文件中使用Zen发现(Zen discovery)机制来管理不同节点.Zen发现是ES自带的默认发现机制,使用多播发现其它 ...

  3. Windows下的Memcache安装与Java部署

    Windows下的Memcache安装: 1. 下载memcached的windows稳定版,解压放某个盘下面,比如在c:\memcached 2. 在终端(也即cmd命令界面)下输入 ‘c:\mem ...

  4. 论 Web 前端加密的意义

    论 Web 前端加密的意义 Web前端密码加密是否有意义? https://www.zhihu.com/question/25539382 https://blog.csdn.net/hla19910 ...

  5. BZOJ4668 冷战(并查集)

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

  6. BZOJ4488 JSOI2015最大公约数

    显然若右端点确定,gcd最多变化log次.容易想到对每一种gcd二分找最远端点,但这样就变成log^3了.注意到右端点右移时,只会造成一些gcd区间的合并,原本gcd相同的区间不可能分裂.由于区间只有 ...

  7. 【转】Visio画用例模型图竟然没有include关系

    转自:http://blog.csdn.net/shuixin536/article/details/8289746 由于电脑上没有安装Rose,因此决定用visio来画UML中的用例模型图,在绘制的 ...

  8. 模拟赛 yjqa

    考场上怕是石乐志. 状态设计还是很自然的,求什么设什么. f[i]表示前i个人安排好,电梯最早回到0层的时间 转移的话,枚举上一次最后一个带走的是谁 f[i]=min(max(f[j],t[i])+2 ...

  9. eclipse tomcat 插件

    下载地址http://www.eclipsetotale.com/tomcatPlugin.html#A3

  10. 模拟实现jdk动态代理

    实现步骤 1.生成代理类的源代码 2.将源代码保存到磁盘 3.使用JavaCompiler编译源代码生成.class字节码文件 4.使用JavaCompiler编译源代码生成.class字节码文件 5 ...