访问者模式(Java)

访问者模式介绍


访问者要解决的核心事项是,在一个稳定的数据结构下,例如用户信息、雇员信息、增加易变的业务访问逻辑。为了增强扩展性,将这两部分的业务解耦的一种设计模式。

说白了访问者模式的核心在于同一个事物不同视角下的访问信息不同,比如一个美女手里拿个冰激凌。小朋友会注意冰激凌,大朋友会找自己喜欢的地方观测敌情。

案例场景模拟


在本案例中我们模拟校园中的学生和老师对于不同用户的访问视角
这个案例场景我们模拟校园中有学生和老师两种身份的用户,那么对于家长和校长关心的角度来看,他们的视角是不同的。家长更关心孩子的成绩和老师的能力,校长更关心老师所在班级学生的人数和升学率{此处模拟的}。
那么这样学生和老师就是一个固定信息的内容,而想让不同视角的用户获取关心的信息,就比较适合使用观察者模式来实现,从而让实体与业务解耦,增强扩展性。但观察者模式的整体类结构相对复杂,需要梳理清楚再开发。

代码实现

访问者模式模型结构

以上是视图展示了代码的核心结构,主要包括不同视角下的不同用户访问模型。
在这里有一个关键的点非常重要,也就是整套设计模式的核心组成部分;visitor.visit(this),这个方法在每一个用户实现类里,包括Student、Teacher。在以下的实现中可以重点关注。

定义用户抽象类

//基础用户信息
public abstract class User {public String name;      // 姓名public String identity;  // 身份;重点班、普通班 | 特级教师、普通教师、实习教师public String clazz;     // 班级public User(String name, String identity, String clazz) {this.name = name;this.identity = identity;this.clazz = clazz;}// 核心访问方法public abstract void accept(Visitor visitor);}
  • 基础信息包括:姓名、身份、班级,也可以是一个业务用户属性类。
  • 定义抽象核心方法,abstract void accept(Visitor visitor),这个方法是为了让后续的用户具体实现者都能提供出一个访问方法,供外部使用。

实现用户信息(老师和学生)

老师类

public class Teacher extends User {public Teacher(String name, String identity, String clazz) {super(name, identity, clazz);}public void accept(Visitor visitor) {visitor.visit(this);}// 升本率public double entranceRatio() {return BigDecimal.valueOf(Math.random() * 100).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();}}

学生类

public class Student extends User {public Student(String name, String identity, String clazz) {super(name, identity, clazz);}public void accept(Visitor visitor) {visitor.visit(this);}public int ranking() {return (int) (Math.random() * 100);}}
  • 这里实现了老师和学生类,都提供了父类的构造函数。
  • 在accept方法中,提供了本地对象访问;visitor.visit(this),这块需要加深理解。
  • 老师和学生类又都单独提供了各自的特性方法;升本率(entranceRatio)、排名(ranking),类似这样的方法可以按照业务需求进行扩展。

定义访问数据接口

public interface Visitor {// 访问学生信息void visit(Student student);// 访问老师信息void visit(Teacher teacher);}
  • 访问的接口比较简单,相同的方法名称,不同的入参用户类型。
  • 让具体的访问类,在实现时可以关注每一种用户类型的具体访问数据对象,例如;升学率和排名。

实现访问类型(校长和家长)

访问者;校长

public class Principal implements Visitor {private Logger logger = LoggerFactory.getLogger(Principal.class);public void visit(Student student) {logger.info("学生信息 姓名:{} 班级:{}", student.name, student.clazz);}public void visit(Teacher teacher) {logger.info("学生信息 姓名:{} 班级:{} 升学率:{}", teacher.name, teacher.clazz, teacher.entranceRatio());}}

访问者;家长

public class Parent implements Visitor {private Logger logger = LoggerFactory.getLogger(Parent.class);public void visit(Student student) {logger.info("学生信息 姓名:{} 班级:{} 排名:{}", student.name, student.clazz, student.ranking());}public void visit(Teacher teacher) {logger.info("老师信息 姓名:{} 班级:{} 级别:{}", teacher.name, teacher.clazz, teacher.identity);}}
  • 以上是两个具体的访问者实现类,他们都有自己的视角需求。
  • 校长关注;学生的名称和班级,老师对这个班级的升学率。
  • 家长关注;自己家孩子的排名,老师的班级和教学水平。

数据看版

public class DataView {List<User> userList = new ArrayList<User>();public DataView() {userList.add(new Student("谢飞机", "重点班", "一年一班"));userList.add(new Student("windy", "重点班", "一年一班"));userList.add(new Student("大毛", "普通班", "二年三班"));userList.add(new Student("Shing", "普通班", "三年四班"));userList.add(new Teacher("BK", "特级教师", "一年一班"));userList.add(new Teacher("娜娜Goddess", "特级教师", "一年一班"));userList.add(new Teacher("dangdang", "普通教师", "二年三班"));userList.add(new Teacher("泽东", "实习教师", "三年四班"));}// 展示public void show(Visitor visitor) {for (User user : userList) {user.accept(visitor);}}}
  • 首先在这个类中初始化了基本的数据,学生和老师的信息。
  • 并提供了一个展示类,通过传入不同的观察者(校长、家长)而差异化的打印信息。

测试

编写测试类

@Test
public void test(){DataView dataView = new DataView();      logger.info("\r\n家长视角访问:");dataView.show(new Parent());     // 家长logger.info("\r\n校长视角访问:");dataView.show(new Principal());  // 校长
}
  • 从测试类可以看到,家长和校长分别是不同的访问视角。

测试结果

23:00:39.726 [main] INFO  org.itstack.demo.design.test.ApiTest -
家长视角访问:
23:00:39.730 [main] INFO  o.i.demo.design.visitor.impl.Parent - 学生信息 姓名:谢飞机 班级:一年一班 排名:62
23:00:39.730 [main] INFO  o.i.demo.design.visitor.impl.Parent - 学生信息 姓名:windy 班级:一年一班 排名:51
23:00:39.730 [main] INFO  o.i.demo.design.visitor.impl.Parent - 学生信息 姓名:大毛 班级:二年三班 排名:16
23:00:39.730 [main] INFO  o.i.demo.design.visitor.impl.Parent - 学生信息 姓名:Shing 班级:三年四班 排名:98
23:00:39.730 [main] INFO  o.i.demo.design.visitor.impl.Parent - 老师信息 姓名:BK 班级:一年一班 级别:特级教师
23:00:39.730 [main] INFO  o.i.demo.design.visitor.impl.Parent - 老师信息 姓名:娜娜Goddess 班级:一年一班 级别:特级教师
23:00:39.730 [main] INFO  o.i.demo.design.visitor.impl.Parent - 老师信息 姓名:dangdang 班级:二年三班 级别:普通教师
23:00:39.730 [main] INFO  o.i.demo.design.visitor.impl.Parent - 老师信息 姓名:泽东 班级:三年四班 级别:实习教师
23:00:39.730 [main] INFO  org.itstack.demo.design.test.ApiTest -
校长视角访问:
23:00:39.731 [main] INFO  o.i.d.design.visitor.impl.Principal - 学生信息 姓名:谢飞机 班级:一年一班
23:00:39.731 [main] INFO  o.i.d.design.visitor.impl.Principal - 学生信息 姓名:windy 班级:一年一班
23:00:39.731 [main] INFO  o.i.d.design.visitor.impl.Principal - 学生信息 姓名:大毛 班级:二年三班
23:00:39.731 [main] INFO  o.i.d.design.visitor.impl.Principal - 学生信息 姓名:Shing 班级:三年四班
23:00:39.733 [main] INFO  o.i.d.design.visitor.impl.Principal - 学生信息 姓名:BK 班级:一年一班 升学率:70.62
23:00:39.733 [main] INFO  o.i.d.design.visitor.impl.Principal - 学生信息 姓名:娜娜Goddess 班级:一年一班 升学率:23.15
23:00:39.734 [main] INFO  o.i.d.design.visitor.impl.Principal - 学生信息 姓名:dangdang 班级:二年三班 升学率:70.98
23:00:39.734 [main] INFO  o.i.d.design.visitor.impl.Principal - 学生信息 姓名:泽东 班级:三年四班 升学率:90.14Process finished with exit code 0
  • 通过测试结果可以看到,家长和校长的访问视角同步,数据也是差异化的。
  • 家长视角看到学生的排名;排名:62、排名:51、排名:16、排名:98。
  • 校长视角看到班级升学率;升学率:70.62、升学率:23.15、升学率:70.98、升学率:90.14。
  • 通过这样的测试结果,可以看到访问者模式的初心和结果,在适合的场景运用合适的模式,非常有利于程序开发。

访问者模式(JAVA)相关推荐

  1. Java设计模式之行为型:访问者模式

    背景: 去医院看病时,医生会给你一个处方单要你去拿药,拿药我们可以分为两步走: (1)去柜台交钱,划价人员会根据处方单上的药进行划价,交钱. (2)去药房拿药,药房工作者同样根据处方单给你相对应的药. ...

  2. Java设计模式(访问者模式-迭代器模式-观察者模式-中介者模式)

    Java设计模式Ⅶ 1.访问者模式 1.1 访问者模式概述 1.2 代码理解 2.迭代器模式 2.1 迭代器模式概述 2.2 代码理解 3.观察者模式 3.1 观察者模式概述 3.2 代码理解 4.中 ...

  3. java设计模式---访问者模式

      Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自 己对java中的接口或抽象类应用有更深的理解.设计模式在java的中型系统中应用广 泛,遵循一定的编程模式,才能使自 ...

  4. 《JAVA与模式》之访问者模式

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

  5. java的visitor模式_java设计模式(二十一)访问者模式(Visitor)

    介绍 访问者模式(Visitor Pattern):表示一个作用于某对象结构中的各元素的操作,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作.访问者模式是一种对象行为型模式. 简单来 ...

  6. 访问者模式的java语言_Java 设计模式系列(二三)访问者模式(Vistor)

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

  7. 图解Java设计模式学习笔记——行为型模式(模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式)

    一.模板方法模式(模板模式)--钩子方法 1.需求-豆浆制作问题 编写制作豆浆的程序,说明如下: 制作豆浆的流程选材-->添加配料-->浸泡-->放到豆浆机打碎. 通过添加不同的配料 ...

  8. 【Java设计模式】:行为型模式—访问者模式

    1. 访问者模式简介 访问者模式,是行为型设计模式之一.访问者模式是一种将数据操作与数据结构分离的设计模式,它可以算是 23 中设计模式中最复杂的一个,但它的使用频率并不是很高,大多数情况下,你并不需 ...

  9. Java的单分派与双分派以及访问者模式的关系

    引言 在学习访问者模式的过程中了解到了单双分派这一词,本文将重点为大家解释Java中的单分派与双分派到底是什么,以及为什么会与访问者模式扯上关系 首先,我们给出一个定义:"Java是一种支持 ...

最新文章

  1. 【转】Asp.Net中Excel操作权限的问题
  2. ux设计师怎样找同类产品_没有预算? 别找借口。 便宜的UX上的UX 2:让我们开始构建。...
  3. 【转】如何将域中的AD数据导入SharePoint
  4. Python爬虫 Day 3
  5. 使用java理解程序逻辑(16)
  6. buuctf-变异凯撒
  7. 全球第一开源ERP Odoo操作手册 数据库简介
  8. 商品分析是什么?该怎么做(入门版)
  9. Lua游戏开发实践指南
  10. N76E003的TM1620B驱动
  11. 【调剂】长江大学张菲菲教授招收硕士生
  12. 注销 睡眠 休眠的区别
  13. 程序员微信名昵称_推荐几个高逼格的微信昵称?
  14. OA选型 三条底线不能碰
  15. opencv matlab配置,MATLAB配置mexopencv
  16. 为什么MD5算法不可逆,但网上有很多网站声称能够解密MD5
  17. ArrayList源码学习第二天全解
  18. Python 实战之 什么是量化交易?它与python之间的关系
  19. Java实现伪查询(全匹配+模糊匹配)
  20. 2022年底总结(被阿里捞的第1、2、3...次)

热门文章

  1. python 连接mysql_Python 连接MySQL
  2. ssm校园社团平台毕业设计源码251554
  3. 基于kintex UltraScale XCKU040的双路QSFP+光纤PCIe卡383 光纤PCIe卡
  4. 银河麒麟系统FT2000 ARM64平台源码编译grub2并制作启动U盘 引导启动长城UF716笔记本
  5. 插画版Kubernetes指南
  6. 【代码1】应用眼中的操作系统;系统调用
  7. 粉象生活优惠券项目优势
  8. ToggleSwitch控件介绍
  9. vue开发的音乐小播放器
  10. 电子榨菜之Mendix漫画