java设计模式-----24、访问者模式
概念:
Visitor模式也叫访问者模式,是行为模式之一,它分离对象的数据和行为,使用Visitor模式,可以不修改已有类的情况下,增加新的操作。
访问者模式的应用示例
比如有一个公园,有一到多个不同的组成部分;该公园存在多个访问者:清洁工A负责打扫公园的A部分,清洁工B负责打扫公园的B部分,公园的管理者负责检点各项事务是否完成,上级领导可以视察公园等等。也就是说,对于同一个公园,不同的访问者有不同的行为操作,而且访问者的种类也可能需要根据时间的推移而变化(行为的扩展性)。根据软件设计的开闭原则(对修改关闭,对扩展开放),我们怎么样实现这种需求呢?
访问者模式的结构

访问者模式的角色和职责
1、 访问者角色(Visitor):为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色。这样访问者就可以通过该元素角色的特定接口直接访问它。
2、具体访问者角色(Concrete Visitor):实现每个由访问者角色(Visitor)声明的操作。
3、元素角色(Element):定义一个Accept操作,它以一个访问者为参数。
4、具体元素角色(Concrete Element):实现由元素角色提供的Accept操作。
5、对象结构角色(Object Structure):这是使用访问者模式必备的角色。它要具备以下特征:能枚举它的元素;可以提供一个高层的接口以允许该访问者访问它的元素;可以是一个复合(组合模式)或是一个集合,如一个列表或一个无序集合。
下面,用代码来实现一下访问者模式
首先,先新建一个公园的各个组成部分(因为有了各个组成部分才能有公园,所以我们先建各个组成部分,再建公园)
新建一个公园各个部分的抽象类(元素角色Element),需要传入一个访问者,一会后面会创建访问者
/*
* 公园每一部分的抽象
*/
public interface ParkElement {
//用来接纳访问者
public void accept(Visitor visitor);
}
再新建公园的各个部分,这是具体元素角色(Concrete Element)
关键代码:在数据基础类里面有一个方法接受访问者,将自身引用传入访问者。
public class ParkA implements ParkElement{
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
public class ParkB implements ParkElement{
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
有了公园的各个部分,我们就可以开始新建公园了,这就是对象结构角色(Object Structure)
/*
* 整个公园,其中包含了公园的各个部分
*/
public class Park implements ParkElement{
private ParkA parkA;
private ParkB parkB; public Park() {
super();
this.parkA = new ParkA();
this.parkB = new ParkB();
} @Override
public void accept(Visitor visitor) {
visitor.visit(this);
parkA.accept(visitor);
parkB.accept(visitor);
} }
有了公园,我们就可以开始建造访问者了,先建造访问者角色(Visitor)
/*
* 其中包含访问公园不同区域的重载方法,其中重载的参数Park,ParkA,PArkB,不仅可以获得公园的信息,还用来作为重载的条件
*/
public interface Visitor {
public void visit(Park park);
public void visit(ParkA parkA);
public void visit(ParkB parkB);
}
然后在建造具体访问者角色,就是具体访问者角色(Concrete Visitor)
/*
* 清洁工A负责公园A的清洁情况
*/
public class VisitorA implements Visitor{ @Override
public void visit(Park park) {
} @Override
public void visit(ParkA parkA) {
System.out.println("清洁工A完成了公园A的卫生");
} @Override
public void visit(ParkB parkB) {
} }
/*
* 清洁工B负责公园B的清洁情况
*/
public class VisitorB implements Visitor{ @Override
public void visit(Park park) {
} @Override
public void visit(ParkA parkA) {
} @Override
public void visit(ParkB parkB) {
System.out.println("清洁工B完成了公园B的卫生");
} }
/*
* 公园管理员负责检查整个公园的卫生情况
*/
public class VisitorManager implements Visitor{ @Override
public void visit(Park park) {
System.out.println("管理员:负责公园的卫生检查");
} @Override
public void visit(ParkA parkA) {
System.out.println("管理员:负责公园A部分的卫生检查");
} @Override
public void visit(ParkB parkB) {
System.out.println("管理员:负责公园B部分的卫生检查");
} }
最后,新建一个客户端
public class MainClass {
public static void main(String[] args) {
Park park = new Park();
Visitor visitorA = new VisitorA();
park.accept(visitorA);
Visitor visitorB = new VisitorB();
park.accept(visitorB);
VisitorManager visitorManager = new VisitorManager();
park.accept(visitorManager);
}
}
结果:

这样,一个访问者模式的例子就完成了,一定把上面的程序看懂
访问者模式的使用意图:
主要将数据结构与数据操作分离,解决了稳定的数据结构和易变的操作耦合问题。
访问者模式的使用场景:
需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,使用访问者模式将这些封装到类中。
1、对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。
2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。
访问者模式的优缺点:
优点:
1、符合单一职责原则。
2、优秀的扩展性。
3、灵活性。
缺点:
1、具体元素对访问者公布细节,违反了迪米特原则。
2、具体元素变更比较困难。
3、违反了依赖倒置原则,依赖了具体类,没有依赖抽象。
注意事项:
访问者可以对功能进行统一,可以做报表、UI、拦截器与过滤器。
java设计模式-----24、访问者模式的更多相关文章
- 折腾Java设计模式之访问者模式
博客原文地址:折腾Java设计模式之访问者模式 访问者模式 Represent an operation to be performed on the elements of an object st ...
- JAVA设计模式之访问者模式
在阎宏博士的<JAVA与模式>一书中开头是这样描述访问者(Visitor)模式的: 访问者模式是对象的行为模式.访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要 ...
- 15.java设计模式之访问者模式
基本需求: 电脑需要键盘鼠标等固定的组件组成 现在分为个人,组织等去买电脑,而同一种组件对不同的人(访问者)做出不同的折扣,从而电脑的价格也不一样 传统的解决方法:在组件内部进行判断访问人的类型,从而 ...
- 由电脑专卖系统引发的Java设计模式:访问者模式
目录 定义 意图 解决问题 何时使用 优缺点 结构 电脑专卖系统 定义 访问者模式是对象的行为型模式,它的目的是封装一些施加于某些数据结构元素之上的操作,一旦这些操作需要修改的话,接收这个操作的数据结 ...
- C#设计模式总结 C#设计模式(22)——访问者模式(Vistor Pattern) C#设计模式总结 .NET Core launch.json 简介 利用Bootstrap Paginator插件和knockout.js完成分页功能 图片在线裁剪和图片上传总结 循序渐进学.Net Core Web Api开发系列【2】:利用Swagger调试WebApi
C#设计模式总结 一. 设计原则 使用设计模式的根本原因是适应变化,提高代码复用率,使软件更具有可维护性和可扩展性.并且,在进行设计的时候,也需要遵循以下几个原则:单一职责原则.开放封闭原则.里氏代替 ...
- Java设计模式——装饰者模式
JAVA 设计模式 装饰者模式 用途 装饰者模式 (Decorator) 动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator 模式相比生成子类更为灵活. 装饰者模式是一种结构式模式 ...
- 浅析JAVA设计模式之工厂模式(一)
1 工厂模式简单介绍 工厂模式的定义:简单地说,用来实例化对象,取代new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式能够动态决定将哪一个类实例化.不用先知道每次要实例化哪一个类. 工 ...
- 乐在其中设计模式(C#) - 访问者模式(Visitor Pattern)
原文:乐在其中设计模式(C#) - 访问者模式(Visitor Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 访问者模式(Visitor Pattern) 作者:webabc ...
- JAVA设计模式--装饰器模式
装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰 ...
- 折腾Java设计模式之建造者模式
博文原址:折腾Java设计模式之建造者模式 建造者模式 Separate the construction of a complex object from its representation, a ...
随机推荐
- <转>(笔记)正则表达式的几种引擎
这篇主要是基于<精通正则表达式>的一篇读书笔记,因为书还没看完,可能以后还会有相关的笔记.(工作以后看书的效率真的很低啊……) 正则引擎主要可以分为基本不同的两大类:一种是DFA(确定性有 ...
- MySQL order by的实现
1.使用索引的已有顺序 2.filesort算法 filesort算法的执行流程 filesort相关的参数 sort_buffer_size 算法排序缓冲区的大小,线程级缓存 max_l ...
- Swfit 里 Array(五)和 NSArray 转换
 只看 Swift Array 到 NSArray Array 里的源代码 extension Array { @inlinable public // @SPI(Foundation) func ...
- vue教程3-05 vue组件数据传递、父子组件数据获取,slot,router路由
vue教程3-05 vue组件数据传递 一.vue默认情况下,子组件也没法访问父组件数据 <!DOCTYPE html> <html lang="en"> ...
- Spring4 mvc+maven 框架搭建(3)
经过前面两个环节,spring mvc的原料已经准备好了,现在就可以正式开始搭建springmvc框架了. 首先先介绍介绍搭建的框架具有的功能: 1)集成log4j,配置好日志相关并可以打印出相关的日 ...
- C# 字符串操作基本过程(Equals、Compare、EndsWith等处理方法)
本文只介绍了比较方法,但是EndsWith,IndexOf等方法均采用相同的过程,先设置CultureInfo(一般情况下调用当前线程的CultureInfo,该语言文化可以通过控制面板设置),然后调 ...
- spring boot + mybatis + druid + redis
接上篇,使用redis做缓存 新建spring boot 工程,添加pom引用 <dependency> <groupId>org.springframework.boot&l ...
- 使用.NET Core与Google Optimization Tools实现员工排班计划Scheduling
上一篇说完<Google Optimization Tools介绍>,让大家初步了解了Google Optimization Tools是一款约束求解(CP)的高效套件.那么我们用.NET ...
- 全网最全的Windows下Anaconda2 / Anaconda3里正确下载安装用来定时任务apscheduler库(图文详解)
不多说,直接上干货! Anaconda2 里 PS C:\Anaconda2\Scripts> PS C:\Anaconda2\Scripts> pip.exe install apsc ...
- [Python 从入门到放弃] 1. 列表的基本操作
''' 列表 Create By 阅后即焚 On 2018.1.29 ''' 1. 列表的定义 列表看起来好像其它编程语言中的数组,但列表具备更加强大的功能,它是Python完备的集合对象,现在,你可 ...