热门标签 | HotTags
当前位置:  开发笔记 > 开放平台 > 正文

Java设计模式之访问者模式使用场景及代码示例

这篇文章主要介绍了Java设计模式之访问者模式使用场景及代码示例,小编觉得还是挺不错的,这里分享给大家,供需要的朋友参考。

Java设计模式访问者模式

模式概念

访问者模式表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。访问者模式适用于数据结构相对稳定算法又易变化的系统,若系统数据结构对象易于变化,则不适合使用访问者模式。访问者模式的优点是增加操作很容易,因为增加操作意味着增加新的访问者。

Visitor应用场景

一定会有的疑问:visitor和iterator的区别:

visitor可以访问不同的对象(只需要在Element定义对应的accept),但是Iterator只能访问相同的对象,最起码要有相同的接口
iterator是不依赖具体实现的,而visitor是依赖具体实现的,因为Visitor会根据访问的具体的对象来采取对应的操作,而iterator最多只是基于相同的接口的泛化实现。

iterator访问的数据结构的操作和数据并未分离,所以拓展功能起来需要修改,违反了开闭原则和单一职责原则。但是因为访问者依赖具体实现,而不是依赖抽象,所以违反了依赖倒置原则

优缺点决定的应用场景

符合单一职责原则,功能上具有良好的拓展性,但是因为依赖具体实现违背了具体实现,所以为类的修改带了麻烦。

具有优良的拓展性,只需要实现新的Visitor来满足新的访问要求。因为数据和操作的分离,防止了添加新的操作污染原来的数据结构。

综上

访问者是一种集中规整模式,特别适合用于大规模重构的项目,在这一个阶段的需求已经非常清晰,原系统的功能点也已经明确,通过访问者模式可以很容易把一些功能进行梳理,达到最终目的功能集中化

模式结构

1)Visitor 抽象访问者角色:
为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色,这样访问者就可以通过该元素角色的特定接口直接访问它。

2)ConcreteVisitor具体访问者角色:
实现Visitor声明的接口。

3)Element抽象受访元素:
定义一个接受访问操作(accept()),它以一个访问者(Visitor)作为参数。

4)ConcreteElement 具体受访元素:
实现了抽象元素(Element)所定义的接受操作接口。

5)ObjectStructure 结构对象角色:
这是使用访问者模式必备的角色。它具备以下特性:能枚举它的元素;可以提供一个高层接口以允许访问者访问它的元素;如有需要,可以设计成一个复合对象或者一个聚集(如一个列表或无序集合)。

Demo

抽象访问者角色:

public interface IVisitor {
 public void accept(Feman feman);
 
 public void accept(Man man);
}

具体访问角色:

public class Visitor implements IVisitor {
 public void accept(Feman feman) {
  System.out.println(feman.getSex() + ":执行相关操作");
 }
 
 public void accept(Man man) {
  System.out.println(man.getSex() + ":执行相关操作");
 }
}

(注)Visitor中设置了同样的名称的方法且方法传参为实现同一接口的不同对象,即受访者元素。

抽象受访元素:

public abstract class Person {
 private String sex;
 public String getSex() {
  return sex;
 }
 public void setSex(String sex) {
  this.sex = sex;
 }
 public void accept(Visitor visitor) {
 };
}

具体受访元素:

public class Man extends Person {
 public Man() {
  this.setSex("男");
 }
 
 @Override
 public void accept(Visitor visitor) {
  visitor.accept(this);
 }
}
public class Feman extends Person {
 public Feman() {
  this.setSex("女");
 }
  
 @Override
 public void accept(Visitor visitor){
  visitor.accept(this);
 }
}

结构对象角色:

public class ObjectStruture {
 public static List getList() {
  List list = new ArrayList();
  list.add(new Man());
  list.add(new Feman());
  list.add(new Feman());
  return list;
 }
}

执行过程:

Visitor visitor = new Visitor();
List list = ObjectStruture.getList();
for (Person e : list) {
 e.accept(visitor);
}

执行结果:

男:执行相关操作
女:执行相关操作
女:执行相关操作

下面是一个完整的代码示例:

public interface Visitor
{
	public void visit(GladiolusConcreteElement gladiolus);
	public void visit(ChrysanthemumConreteElement chrysanthemum);
}
public interface FlowerElement
{
	public void accept(Visitor visitor);
}
public class GladiolusConcreteElement implements FlowerElement
{
	@Override
	 public void accept(final Visitor visitor)
	 {
		visitor.visit(this);
	}
}
public class ChrysanthemumConreteElement implements FlowerElement
{
	@Override
	 public void accept(final Visitor visitor)
	 {
		visitor.visit(this);
	}
}
public class GladiolusVisitor implements Visitor
{
	@Override
	 public void visit(final GladiolusConcreteElement gladiolus)
	 {
		System.out.println(this.getClass().getSimpleName() + " access " + gladiolus.getClass().getSimpleName());
	}
	@Override
	 public void visit(final ChrysanthemumConreteElement chrysanthemum)
	 {
		System.out.println(this.getClass().getSimpleName() + " access " + chrysanthemum.getClass().getSimpleName());
	}
}
public class ChrysanthemumConreteElement implements FlowerElement
{
	@Override
	 public void accept(final Visitor visitor)
	 {
		visitor.visit(this);
	}
}
public class ObjectStructure
{
	private final List elements = new ArrayList();
	public void addElement(final FlowerElement e)
	 {
		elements.add(e);
	}
	public void removeElement(final FlowerElement e)
	 {
		elements.remove(e);
	}
	public void accept(final Visitor visitor)
	 {
		for (final FlowerElement e : elements)
		  {
			e.accept(visitor);
		}
	}
}
public class Client
{
	public static void main(final String[] args)
	 {
		final ObjectStructure os = new ObjectStructure();
		os.addElement(new GladiolusConcreteElement());
		os.addElement(new ChrysanthemumConreteElement());
		final GladiolusVisitor gVisitor = new GladiolusVisitor();
		final ChrysanthemumVisitor chVisitor = new ChrysanthemumVisitor();
		os.accept(gVisitor);
		os.accept(chVisitor);
	}
}

运行结果:

GladiolusVisitor access GladiolusConcreteElement
GladiolusVisitor access ChrysanthemumConreteElement
ChrysanthemumVisitor access GladiolusConcreteElement
ChrysanthemumVisitor access ChrysanthemumConreteElement

总结

以上就是本文关于Java设计模式之访问者模式使用场景及代码示例的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:Java编程—在测试中考虑多态、Java实现微信公众平台朋友圈分享功能详细代码、Java编程BigDecimal用法实例分享等,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持。


推荐阅读
  • 学习SLAM的女生,很酷
    本文介绍了学习SLAM的女生的故事,她们选择SLAM作为研究方向,面临各种学习挑战,但坚持不懈,最终获得成功。文章鼓励未来想走科研道路的女生勇敢追求自己的梦想,同时提到了一位正在英国攻读硕士学位的女生与SLAM结缘的经历。 ... [详细]
  • 近年来,大数据成为互联网世界的新宠儿,被列入阿里巴巴、谷歌等公司的战略规划中,也在政府报告中频繁提及。据《大数据人才报告》显示,目前全国大数据人才仅46万,未来3-5年将出现高达150万的人才缺口。根据领英报告,数据剖析人才供应指数最低,且跳槽速度最快。中国商业结合会数据剖析专业委员会统计显示,未来中国基础性数据剖析人才缺口将高达1400万。目前BAT企业中,60%以上的招聘职位都是针对大数据人才的。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • Go语言实现堆排序的详细教程
    本文主要介绍了Go语言实现堆排序的详细教程,包括大根堆的定义和完全二叉树的概念。通过图解和算法描述,详细介绍了堆排序的实现过程。堆排序是一种效率很高的排序算法,时间复杂度为O(nlgn)。阅读本文大约需要15分钟。 ... [详细]
  • 提升Python编程效率的十点建议
    本文介绍了提升Python编程效率的十点建议,包括不使用分号、选择合适的代码编辑器、遵循Python代码规范等。这些建议可以帮助开发者节省时间,提高编程效率。同时,还提供了相关参考链接供读者深入学习。 ... [详细]
  • 本文讨论了同事工资打听的话题,包括同工不同酬现象、打探工资的途径、为什么打听别人的工资、职业的本质、商业价值与工资的关系,以及如何面对同事工资比自己高的情况和凸显自己的商业价值。故事中的阿巧发现同事的工资比自己高后感到不满,通过与老公、闺蜜交流和搜索相关关键词来寻求解决办法。 ... [详细]
  • 本文介绍了在Win10上安装WinPythonHadoop的详细步骤,包括安装Python环境、安装JDK8、安装pyspark、安装Hadoop和Spark、设置环境变量、下载winutils.exe等。同时提醒注意Hadoop版本与pyspark版本的一致性,并建议重启电脑以确保安装成功。 ... [详细]
  • 【Windows】实现微信双开或多开的方法及步骤详解
    本文介绍了在Windows系统下实现微信双开或多开的方法,通过安装微信电脑版、复制微信程序启动路径、修改文本文件为bat文件等步骤,实现同时登录两个或多个微信的效果。相比于使用虚拟机的方法,本方法更简单易行,适用于任何电脑,并且不会消耗过多系统资源。详细步骤和原理解释请参考本文内容。 ... [详细]
  • 如何基于ggplot2构建相关系数矩阵热图以及一个友情故事
    本文介绍了如何在rstudio中安装ggplot2,并使用ggplot2构建相关系数矩阵热图。同时,通过一个友情故事,讲述了真爱难觅的故事背后的数据量化和皮尔逊相关系数的概念。故事中的小伙伴们在本科时参加各种考试,其中有些沉迷网络游戏,有些热爱体育,通过他们的故事,展示了不同兴趣和特长对学习和成绩的影响。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 本文讨论了如何在微信支付宝两套小程序中生成一张二维码,实现支付宝扫码进入支付宝小程序和微信扫码进入微信小程序的对应桌号进行点餐的功能,提供了一些实现方案供参考。 ... [详细]
  • jmeter实践:从csv中获取带引号的数据详情的技巧和运行全部数据的方法
    本文分享了jmeter实践中从csv中获取带引号的数据的解决办法,包括设置CSV Data Set Config和运行脚本获取数据的方法。另外还介绍了循环运行csv中全部数据的解决方法,避免每次修改csv用例都需要修改脚本的麻烦。通过了解和掌握工具的细节点,可以更好地解决问题和提高技术水平。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • 仙贝旅行是日本最大的旅游服务平台之一,为广大用户提供优质的日本定制游服务。随着用户数量的增长,仙贝旅行决定与智齿科技合作,全面替换原有客服系统,打造全新的在线客服体系。该体系具备多渠道快速接入的能力,让仙贝旅行轻松与各个渠道的接入用户完成沟通。同时,机器人与人工协同发力,提升客户服务水平。 ... [详细]
  • 数字账号安全与数据资产问题的研究及解决方案
    本文研究了数字账号安全与数据资产问题,并提出了解决方案。近期,大量QQ账号被盗事件引起了广泛关注。欺诈者对数字账号的价值认识超过了账号主人,因此他们不断攻击和盗用账号。然而,平台和账号主人对账号安全问题的态度不正确,只有用户自身意识到问题的严重性并采取行动,才能推动平台优先解决这些问题。本文旨在提醒用户关注账号安全,并呼吁平台承担起更多的责任。令牌云团队对此进行了长期深入的研究,并提出了相应的解决方案。 ... [详细]
author-avatar
醒九九爷
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有