一句话

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

概括

解析

情人节到了,要给每个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. Caused by: redis.clients.jedis.exceptions.JedisDataException: WRONGTYPE Operation against a key holding the wrong kind of value

    对错误类型key的操作,也就是说redis中没有你当前操作的这个key,而你用这个key去执行某些操作!检查key是否正确

  2. Web-request内置对象在JSP编程中的应用

  3. 算法(12)Pascal's Triangle II

    题目:输出帕斯卡三角的第k行 思路:真没思路,发现几个easy的题不容易想!这里的大致思路是从后开始更新第k行!

  4. Nginx学习笔记之加强篇

    在上一篇文章Nginx学习笔记之应用篇中,我们已经可以正式运行自己的网站了.但是在使用Nginx服务器时还需要注意几个问题: 1.Nginx服务器上配置的单个站点的并发量不超过1024 2.Nginx ...

  5. WebSocket对象的创建及其与WebSocket服务器的连接(5)

    WebSocket接口的使用非常简单,要连接通信端点,只需要创建一个新的WebSocket实例,并提供希望连接URL. //ws://和wss://前缀分别表示WebSocket连接和安全的WebSo ...

  6. Div+Css中transparent制作奥运五环

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. flask-sqlalchemy 用法总结

    Flask-SQLAlchemy是一个Flask扩展,能够支持多种数据库后台,我们可以不需要关心SQL的处理细节,操作数据库,一个基本关系对应一个类,而一个实体对应类的实例对象.Flask是一个轻量级 ...

  8. P2127 序列排序

    题目描述 小C有一个N个数的整数序列,这个序列的中的数两两不同.小C每次可以交换序列中的任意两个数,代价为这两个数之和.小C希望将整个序列升序排序,问小C需要的最小代价是多少? 输入输出格式 输入格式 ...

  9. [Leetcode] The minimum depth of binary tree二叉树的最小深度

    Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the shor ...

  10. BZOJ4567 [Scoi2016]背单词 【trie树 + 贪心】

    题目链接 BZOJ4567 题解 题意真是鬼畜= = 意思就是说我们应先将一个串的所有后缀都插入之后再插入这个串,产生代价为其到上一个后缀的距离 我们翻转一下串,转化为前缀,就可以建\(trie\)树 ...